diff --git a/lang/en_utf8/portfolio.php b/lang/en_utf8/portfolio.php index 1655f9cf6a4..d7935ffed9e 100644 --- a/lang/en_utf8/portfolio.php +++ b/lang/en_utf8/portfolio.php @@ -76,6 +76,7 @@ $string['noavailableplugins'] = 'Sorry, but there are no available portfolios fo $string['nocallbackfile'] = 'Something in the module you\'re trying to export from is broken - couldn\'t find a required file ($a)'; $string['nocallbackclass'] = 'Could not find the callback class to use ($a)'; $string['nocommonformats'] = 'No common formats between any available portfolio plugin and the calling location $a'; +$string['noclassbeforeformats'] = 'You must set the callback class before calling set_formats in portfolio_button'; $string['nopermissions'] = 'Sorry but you do not have the required permissions to export files from this area'; $string['nonprimative'] = 'A non primative value was passed as a callback argument to portfolio_add_button. Refusing to continue. The key was $a->key and the value was $a->value'; $string['notexportable'] = 'Sorry, but the type of content you are trying to export is not exportable'; diff --git a/lib/portfolio/plugin.php b/lib/portfolio/plugin.php index 7de6edd4c76..f6a72407900 100644 --- a/lib/portfolio/plugin.php +++ b/lib/portfolio/plugin.php @@ -440,7 +440,7 @@ abstract class portfolio_plugin_base { * and should call parent::__construct afterwards * * @param int $instanceid id of plugin instance to construct - * @param mixed $record stdclass object or named array - use this is you already have the record to avoid another query + * @param mixed $record stdclass object or named array - use this i you already have the record to avoid another query * * @return object subclass of portfolio_plugin_base */ diff --git a/lib/portfoliolib.php b/lib/portfoliolib.php index aee61ec03f6..b57c375d886 100644 --- a/lib/portfoliolib.php +++ b/lib/portfoliolib.php @@ -135,6 +135,12 @@ class portfolio_add_button { } /* + * sets the available export formats for this content + * this function will also poll the static function in the caller class + * and make sure we're not overriding a format that has nothing to do with mimetypes + * eg if you pass IMAGE here but the caller can export LEAP it will keep LEAP as well. + * see portfolio_most_specific_formats for more information + * * @param array $formats if the calling code knows better than the static method on the calling class (supported_formats) * eg, if it's going to be a single file, or if you know it's HTML, you can pass it here instead * this is almost always the case so you should always use this. @@ -145,18 +151,13 @@ class portfolio_add_button { $formats = array($formats); } if (empty($formats)) { - if (empty($this->callbackclass)) { - throw new portfolio_button_exception('noformatsorclass', 'portfolio'); - } - $formats = call_user_func(array($this->callbackclass, 'supported_formats')); + $formats = array(); } - $allformats = portfolio_supported_formats(); - foreach ($formats as $f) { - if (!array_key_exists($f, $allformats)) { - throw new portfolio_button_exception('invalidformat', 'portfolio', $f); - } + if (empty($this->callbackclass)) { + throw new portfolio_button_exception('noclassbeforeformats', 'portfolio'); } - $this->formats = $formats; + $callerformats = call_user_func(array($this->callbackclass, 'supported_formats')); + $this->formats = portfolio_most_specific_formats($formats, $callerformats); } /* @@ -499,6 +500,35 @@ function portfolio_supported_formats_intersect($callerformats, $pluginformats) { return $intersection; } +/** +* return the combination of the two arrays of formats with duplicates in terms of specificity removed +* use case: a module is exporting a single file, so the general formats would be FILE and MBKP +* while the specific formats would be the specific subclass of FILE based on mime (say IMAGE) +* and this function would return IMAGE and MBKP +* +* @param array $specificformats array of more specific formats (eg based on mime detection) +* @param array $generalformats array of more general formats (usually more supported) +* +* @return array merged formats with dups removed +*/ +function portfolio_most_specific_formats($specificformats, $generalformats) { + $allformats = portfolio_supported_formats(); + foreach ($specificformats as $f) { + // look for something less specific and remove it, ie outside of the inheritance tree of the current formats. + if (!array_key_exists($f, $allformats)) { + throw new portfolio_button_exception('invalidformat', 'portfolio', $f); + } + $fobj = new $allformats[$f]; + foreach ($generalformats as $key => $cf) { + $cfclass = $allformats[$cf]; + if ($fobj instanceof $cfclass) { + unset($generalformats[$cf]); + } + } + } + return array_merge(array_values($specificformats), array_values($generalformats)); +} + /** * helper function to return an instance of a plugin (with config loaded) * diff --git a/mod/assignment/lib.php b/mod/assignment/lib.php index 06302a1c5d3..b149ea2e614 100644 --- a/mod/assignment/lib.php +++ b/mod/assignment/lib.php @@ -1714,15 +1714,15 @@ class assignment_base { $path = $browser->encodepath($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/assignment_submission/'.$userid.'/'.$filename); $output .= ''.$icon.''.s($filename).''; if ($this->portfolio_exportable() && has_capability('mod/assignment:exportownsubmission', $this->context)) { - $button->set_formats(portfolio_format_from_file($file)); $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'file' => $file->get_id())); + $button->set_formats(portfolio_format_from_file($file)); $output .= $button->to_html(PORTFOLIO_ADD_ICON_LINK); } $output .= '
'; } if (count($files) > 1 && $this->portfolio_exportable() && has_capability('mod/assignment:exportownsubmission', $this->context)) { - $button->set_formats(PORTFOLIO_PORMAT_FILE); $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id)); + $button->set_formats(PORTFOLIO_PORMAT_FILE); $output .= '
' . $button->to_html(); } } diff --git a/mod/assignment/type/upload/assignment.class.php b/mod/assignment/type/upload/assignment.class.php index 1dc391b41ce..a60398021b1 100644 --- a/mod/assignment/type/upload/assignment.class.php +++ b/mod/assignment/type/upload/assignment.class.php @@ -365,8 +365,8 @@ class assignment_upload extends assignment_base { $output .= '
'; } if (count($files) > 1 && has_capability('mod/assignment:exportownsubmission', $this->context)) { - $button->set_formats(PORTFOLIO_FORMAT_FILE); $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id), '/mod/assignment/lib.php'); + $button->set_formats(PORTFOLIO_FORMAT_FILE); $output .= $button->to_html(); } }