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 .= '
'.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();
}
}