diff --git a/lang/en/portfolio.php b/lang/en/portfolio.php
index 8bdb88e324fa4..d0bf89a67559a 100644
--- a/lang/en/portfolio.php
+++ b/lang/en/portfolio.php
@@ -145,7 +145,8 @@
$string['mustsetcallbackoptions'] = 'You must set the callback options either in the portfolio_add_button constructor or using the set_callback_options method';
$string['noavailableplugins'] = 'Sorry, but there are no available portfolios for you to export to';
$string['nocallbackclass'] = 'Could not find the callback class to use ({$a})';
-$string['nocallbackfile'] = 'Something in the module you\'re trying to export from is broken - couldn\'t find a required file ({$a})';
+$string['nocallbackcomponent'] = 'Could not find the component specified {$a}.';
+$string['nocallbackfile'] = 'Something in the module you\'re trying to export from is broken - couldn\'t find a required portfolio file';
$string['noclassbeforeformats'] = 'You must set the callback class before calling set_formats in portfolio_button';
$string['nocommonformats'] = 'No common formats between any available portfolio plugin and the calling location {$a->location} (caller supported {$a->formats})';
$string['noinstanceyet'] = 'Not yet selected';
diff --git a/lib/db/install.xml b/lib/db/install.xml
old mode 100644
new mode 100755
index 96dc090f9db6e..aee878fddbc64
--- a/lib/db/install.xml
+++ b/lib/db/install.xml
@@ -2303,8 +2303,9 @@
-
-
+
+
+
diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php
index 8ade318b874f0..6e904b221755d 100644
--- a/lib/db/upgrade.php
+++ b/lib/db/upgrade.php
@@ -1399,5 +1399,20 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2012110201.00);
}
+ if ($oldversion < 2012110700.01) {
+
+ // Define field caller_component to be added to portfolio_log.
+ $table = new xmldb_table('portfolio_log');
+ $field = new xmldb_field('caller_component', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'caller_file');
+
+ // Conditionally launch add field caller_component.
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ // Main savepoint reached.
+ upgrade_main_savepoint(true, 2012110700.01);
+ }
+
return true;
}
diff --git a/lib/portfolio/exporter.php b/lib/portfolio/exporter.php
index 79bfc8f6b4f62..3225ddf6af307 100644
--- a/lib/portfolio/exporter.php
+++ b/lib/portfolio/exporter.php
@@ -66,10 +66,10 @@ class portfolio_exporter {
public $instancefile;
/**
- * @var string the file to include that contains the class definition of
+ * @var string the component that contains the class definition of
* the caller object used to re-waken the object after sleep
*/
- public $callerfile;
+ public $callercomponent;
/** @var int the current stage of the export */
private $stage;
@@ -115,16 +115,16 @@ class portfolio_exporter {
*
* @param portfolio_plugin_base $instance portfolio instance (passed by reference)
* @param portfolio_caller_base $caller portfolio caller (passed by reference)
- * @param string $callerfile path to callerfile (relative to dataroot)
+ * @param string $callercomponent the name of the callercomponent
*/
- public function __construct(&$instance, &$caller, $callerfile) {
+ public function __construct(&$instance, &$caller, $callercomponent) {
$this->instance =& $instance;
$this->caller =& $caller;
if ($instance) {
$this->instancefile = 'portfolio/' . $instance->get('plugin') . '/lib.php';
$this->instance->set('exporter', $this);
}
- $this->callerfile = $callerfile;
+ $this->callercomponent = $callercomponent;
$this->stage = PORTFOLIO_STAGE_CONFIG;
$this->caller->set('exporter', $this);
$this->alreadystolen = array();
@@ -395,7 +395,13 @@ public function process_stage_confirm() {
foreach ($previous as $row) {
$previousstr .= userdate($row->time);
if ($row->caller_class != get_class($this->caller)) {
- require_once($CFG->dirroot . '/' . $row->caller_file);
+ if (!empty($row->caller_file)) {
+ portfolio_include_callback_file($row->caller_file);
+ } else if (!empty($row->caller_component)) {
+ portfolio_include_callback_file($row->caller_component);
+ } else { // Ok, that's weird - this should never happen. Is the apocalypse coming?
+ continue;
+ }
$previousstr .= ' (' . call_user_func(array($row->caller_class, 'display_name')) . ')';
}
$previousstr .= '
';
@@ -522,15 +528,16 @@ public function process_stage_send() {
public function log_transfer() {
global $DB;
$l = array(
- 'userid' => $this->user->id,
- 'portfolio' => $this->instance->get('id'),
- 'caller_file' => $this->callerfile,
- 'caller_sha1' => $this->caller->get_sha1(),
- 'caller_class' => get_class($this->caller),
- 'continueurl' => $this->instance->get_static_continue_url(),
- 'returnurl' => $this->caller->get_return_url(),
- 'tempdataid' => $this->id,
- 'time' => time(),
+ 'userid' => $this->user->id,
+ 'portfolio' => $this->instance->get('id'),
+ 'caller_file'=> '',
+ 'caller_component' => $this->callercomponent,
+ 'caller_sha1' => $this->caller->get_sha1(),
+ 'caller_class' => get_class($this->caller),
+ 'continueurl' => $this->instance->get_static_continue_url(),
+ 'returnurl' => $this->caller->get_return_url(),
+ 'tempdataid' => $this->id,
+ 'time' => time(),
);
$DB->insert_record('portfolio_log', $l);
}
@@ -681,7 +688,14 @@ public static function rewaken_object($id) {
if ($exporter->instancefile) {
require_once($CFG->dirroot . '/' . $exporter->instancefile);
}
- require_once($CFG->dirroot . '/' . $exporter->callerfile);
+ if (!empty($exporter->callerfile)) {
+ portfolio_include_callback_file($exporter->callerfile);
+ } else if (!empty($exporter->callercomponent)) {
+ portfolio_include_callback_file($exporter->callercomponent);
+ } else {
+ return; // Should never get here!
+ }
+
$exporter = unserialize(serialize($exporter));
if (!$exporter->get('id')) {
// workaround for weird case
diff --git a/lib/portfoliolib.php b/lib/portfoliolib.php
index 04a2223aaf21e..37d91dc0fd158 100644
--- a/lib/portfoliolib.php
+++ b/lib/portfoliolib.php
@@ -60,12 +60,12 @@
* This class can be used like this:
*
* $button = new portfolio_add_button();
- * $button->set_callback_options('name_of_caller_class', array('id' => 6), '/your/mod/lib.php');
- * $button->render(PORTFOLIO_ADD_FULL_FORM, get_string('addeverythingtoportfolio', 'yourmodule'));
+ * $button->set_callback_options('name_of_caller_class', array('id' => 6), 'yourcomponent'); eg. mod_forum
+ * $button->render(PORTFOLIO_ADD_FULL_FORM, get_string('addeverythingtoportfolio', 'yourcomponent'));
*
* or like this:
*
- * $button = new portfolio_add_button(array('callbackclass' => 'name_of_caller_class', 'callbackargs' => array('id' => 6), 'callbackfile' => '/your/mod/lib.php'));
+ * $button = new portfolio_add_button(array('callbackclass' => 'name_of_caller_class', 'callbackargs' => array('id' => 6), 'callbackcomponent' => 'yourcomponent')); eg. mod_forum
* $somehtml .= $button->to_html(PORTFOLIO_ADD_TEXT_LINK);
*
*{@link http://docs.moodle.org/dev/Adding_a_Portfolio_Button_to_a_page} for more information
@@ -84,7 +84,7 @@ class portfolio_add_button {
private $callbackargs;
/** @var string caller file */
- private $callbackfile;
+ private $callbackcomponent;
/** @var array array of more specific formats (eg based on mime detection) */
private $formats;
@@ -105,7 +105,7 @@ class portfolio_add_button {
* @param array $options keyed array of options:
* key 'callbackclass': name of the caller class (eg forum_portfolio_caller')
* key 'callbackargs': the array of callback arguments your caller class wants passed to it in the constructor
- * key 'callbackfile': the file containing the class definition of your caller class.
+ * key 'callbackcomponent': the file containing the class definition of your caller class.
* See set_callback_options for more information on these three.
* key 'formats': an array of PORTFOLIO_FORMATS this caller will support
* See set_formats or set_format_by_file for more information on this.
@@ -121,54 +121,42 @@ public function __construct($options=null) {
if (empty($options)) {
return true;
}
- $constructoroptions = array('callbackclass', 'callbackargs', 'callbackfile', 'formats');
+ $constructoroptions = array('callbackclass', 'callbackargs', 'callbackcomponent');
foreach ((array)$options as $key => $value) {
if (!in_array($key, $constructoroptions)) {
throw new portfolio_button_exception('invalidbuttonproperty', 'portfolio', $key);
}
- $this->{$key} = $value;
}
+
+ $this->set_callback_options($options['callbackclass'], $options['callbackargs'], $options['callbackcomponent']);
}
/**
* Function to set the callback options
*
- * @param string $class Name of the class containing the callback functions
- * activity modules should ALWAYS use their name_portfolio_caller
- * other locations must use something unique
+ * @param string $class Name of the class containing the callback functions
+ * activity components should ALWAYS use their name_portfolio_caller
+ * other locations must use something unique
* @param array $argarray This can be an array or hash of arguments to pass
- * back to the callback functions (passed by reference)
- * these MUST be primatives to be added as hidden form fields.
- * and the values get cleaned to PARAM_ALPHAEXT or PARAM_FLOAT or PARAM_PATH
- * @param string $file This can be autodetected if it's in the same file as your caller,
- * but often, the caller is a script.php and the class in a lib.php
- * so you can pass it here if necessary.
- * This path should be relative (ie, not include) dirroot, eg '/mod/forum/lib.php'
+ * back to the callback functions (passed by reference)
+ * these MUST be primatives to be added as hidden form fields.
+ * and the values get cleaned to PARAM_ALPHAEXT or PARAM_FLOAT or PARAM_PATH
+ * @param string $component This is the name of the component in Moodle, eg 'mod_forum'
*/
- public function set_callback_options($class, array $argarray, $file=null) {
+ public function set_callback_options($class, array $argarray, $component) {
global $CFG;
- if (empty($file)) {
- $backtrace = debug_backtrace();
- if (!array_key_exists(0, $backtrace) || !array_key_exists('file', $backtrace[0]) || !is_readable($backtrace[0]['file'])) {
- throw new portfolio_button_exception('nocallbackfile', 'portfolio');
- }
- $file = substr($backtrace[0]['file'], strlen($CFG->dirroot));
- } else if (!is_readable($CFG->dirroot . $file)) {
- throw new portfolio_button_exception('nocallbackfile', 'portfolio', '', $file);
- }
- $this->callbackfile = $file;
- require_once($CFG->libdir . '/portfolio/caller.php'); // require the base class first
- require_once($CFG->dirroot . $file);
- if (!class_exists($class)) {
- throw new portfolio_button_exception('nocallbackclass', 'portfolio', '', $class);
- }
+ // Require the base class first before any other files.
+ require_once($CFG->libdir . '/portfolio/caller.php');
- // this will throw exceptions
- // but should not actually do anything other than verify callbackargs
+ // Include any potential callback files and check for errors.
+ portfolio_include_callback_file($component, $class);
+
+ // This will throw exceptions but should not actually do anything other than verify callbackargs.
$test = new $class($argarray);
unset($test);
+ $this->callbackcomponent = $component;
$this->callbackclass = $class;
$this->callbackargs = $argarray;
}
@@ -278,7 +266,7 @@ public function to_html($format=null, $addstr=null) {
if (!$this->is_renderable()) {
return;
}
- if (empty($this->callbackclass) || empty($this->callbackfile)) {
+ if (empty($this->callbackclass) || empty($this->callbackcomponent)) {
throw new portfolio_button_exception('mustsetcallbackoptions', 'portfolio');
}
if (empty($this->formats)) {
@@ -297,7 +285,7 @@ public function to_html($format=null, $addstr=null) {
$url->param('ca_' . $key, $value);
}
$url->param('sesskey', sesskey());
- $url->param('callbackfile', $this->callbackfile);
+ $url->param('callbackcomponent', $this->callbackcomponent);
$url->param('callbackclass', $this->callbackclass);
$url->param('course', (!empty($COURSE)) ? $COURSE->id : 0);
$url->param('callerformats', implode(',', $this->formats));
@@ -421,12 +409,12 @@ public function get_callbackargs() {
}
/**
- * Getter for $callbackfile property
+ * Getter for $callbackcomponent property
*
* @return string
*/
- public function get_callbackfile() {
- return $this->callbackfile;
+ public function get_callbackcomponent() {
+ return $this->callbackcomponent;
}
/**
@@ -1271,6 +1259,89 @@ function portfolio_rewrite_pluginfile_url_callback($contextid, $component, $file
return $format->file_output($file, $options);
}
+/**
+ * Function to require any potential callback files, throwing exceptions
+ * if an issue occurs.
+ *
+ * @param string $component This is the name of the component in Moodle, eg 'mod_forum'
+ * @param string $class Name of the class containing the callback functions
+ * activity components should ALWAYS use their name_portfolio_caller
+ * other locations must use something unique
+ */
+function portfolio_include_callback_file($component, $class = null) {
+ global $CFG;
+ require_once($CFG->libdir . '/adminlib.php');
+
+ // It's possible that they are passing a file path rather than passing a component.
+ // We want to try and convert this to a component name, eg. mod_forum.
+ $pos = strrpos($component, '/');
+ if ($pos !== false) {
+ // Get rid of the first slash (if it exists).
+ $component = ltrim($component, '/');
+ // Get a list of valid plugin types.
+ $plugintypes = get_plugin_types(false);
+ // Assume it is not valid for now.
+ $isvalid = false;
+ // Go through the plugin types.
+ foreach ($plugintypes as $type => $path) {
+ if (strrpos($component, $path) === 0) {
+ // Found the plugin type.
+ $isvalid = true;
+ $plugintype = $type;
+ $pluginpath = $path;
+ }
+ }
+ // Throw exception if not a valid component.
+ if (!$isvalid) {
+ throw new coding_exception('Somehow a non-valid plugin path was passed, could be a hackz0r attempt, exiting.');
+ }
+ // Remove the file name.
+ $component = trim(substr($component, 0, $pos), '/');
+ // Replace the path with the type.
+ $component = str_replace($pluginpath, $plugintype, $component);
+ // Ok, replace '/' with '_'.
+ $component = str_replace('/', '_', $component);
+ // Place a debug message saying the third parameter should be changed.
+ debugging('The third parameter sent to the function set_callback_options should be the component name, not a file path, please update this.', DEBUG_DEVELOPER);
+ }
+
+ // Check that it is a valid component.
+ if (!get_component_version($component)) {
+ throw new portfolio_button_exception('nocallbackcomponent', 'portfolio', '', $component);
+ }
+
+ // Obtain the component's location.
+ if (!$componentloc = get_component_directory($component)) {
+ throw new portfolio_button_exception('nocallbackcomponent', 'portfolio', '', $component);
+ }
+
+ // Check if the component contains the necessary file for the portfolio plugin.
+ // These are locallib.php, portfoliolib.php and portfolio_callback.php.
+ $filefound = false;
+ if (file_exists($componentloc . '/locallib.php')) {
+ $filefound = true;
+ require_once($componentloc . '/locallib.php');
+ }
+ if (file_exists($componentloc . '/portfoliolib.php')) {
+ $filefound = true;
+ debugging('Please standardise your plugin by renaming your portfolio callback file to locallib.php, or if that file already exists moving the portfolio functionality there.', DEBUG_DEVELOPER);
+ require_once($componentloc . '/portfoliolib.php');
+ }
+ if (file_exists($componentloc . '/portfolio_callback.php')) {
+ $filefound = true;
+ debugging('Please standardise your plugin by renaming your portfolio callback file to locallib.php, or if that file already exists moving the portfolio functionality there.', DEBUG_DEVELOPER);
+ require_once($componentloc . '/portfolio_callback.php');
+ }
+
+ // Ensure that we found a file we can use, if not throw an exception.
+ if (!$filefound) {
+ throw new portfolio_button_exception('nocallbackfile', 'portfolio', '', $component);
+ }
+
+ if (!is_null($class) && !class_exists($class)) {
+ throw new portfolio_button_exception('nocallbackclass', 'portfolio', '', $class);
+ }
+}
/**
* Go through all the @@PLUGINFILE@@ matches in some text,
diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php
index a4ab9396c5131..ddc9d0135433a 100644
--- a/mod/assign/locallib.php
+++ b/mod/assign/locallib.php
@@ -61,7 +61,8 @@
require_once($CFG->dirroot.'/mod/assign/gradingtable.php');
/** Include eventslib.php */
require_once($CFG->libdir.'/eventslib.php');
-
+/** Include portfolio caller.php */
+require_once($CFG->libdir . '/portfolio/caller.php');
/**
* Standard base class for mod_assign (assignment types).
@@ -1759,7 +1760,9 @@ public function render_editor_content($filearea, $submissionid, $plugintype, $ed
require_once($CFG->libdir . '/portfoliolib.php');
$button = new portfolio_add_button();
- $button->set_callback_options('assign_portfolio_caller', array('cmid' => $this->get_course_module()->id, 'sid' => $submissionid, 'plugin' => $plugintype, 'editor' => $editor, 'area'=>$filearea), '/mod/assign/portfolio_callback.php');
+ $button->set_callback_options('assign_portfolio_caller', array('cmid' => $this->get_course_module()->id,
+ 'sid' => $submissionid, 'plugin' => $plugintype, 'editor' => $editor, 'area'=>$filearea),
+ 'mod_assign');
$fs = get_file_storage();
if ($files = $fs->get_area_files($this->context->id, $component,$filearea, $submissionid, "timemodified", false)) {
@@ -4545,3 +4548,250 @@ public static function get_user_id_for_uniqueid_static($assignid, $uniqueid) {
}
+/**
+ * portfolio caller class for mod_assign.
+ *
+ * @package mod_assign
+ * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class assign_portfolio_caller extends portfolio_module_caller_base {
+
+ /** @var int callback arg - the id of submission we export */
+ protected $sid;
+
+ /** @var string component of the submission files we export*/
+ protected $component;
+
+ /** @var string callback arg - the area of submission files we export */
+ protected $area;
+
+ /** @var int callback arg - the id of file we export */
+ protected $fileid;
+
+ /** @var int callback arg - the cmid of the assignment we export */
+ protected $cmid;
+
+ /** @var string callback arg - the plugintype of the editor we export */
+ protected $plugin;
+
+ /** @var string callback arg - the name of the editor field we export */
+ protected $editor;
+
+ /**
+ * callback arg for a single file export
+ */
+ public static function expected_callbackargs() {
+ return array(
+ 'cmid' => true,
+ 'sid' => false,
+ 'area' => false,
+ 'component' => false,
+ 'fileid' => false,
+ 'plugin' => false,
+ 'editor' => false,
+ );
+ }
+
+ /**
+ * the constructor
+ * @param array $callbackargs
+ */
+ function __construct($callbackargs) {
+ parent::__construct($callbackargs);
+ $this->cm = get_coursemodule_from_id('assign', $this->cmid, 0, false, MUST_EXIST);
+ }
+
+ /**
+ *
+ * Load data needed for the portfolio export
+ *
+ * If the assignment type implements portfolio_load_data(), the processing is delegated
+ * to it. Otherwise, the caller must provide either fileid (to export single file) or
+ * submissionid and filearea (to export all data attached to the given submission file area) via callback arguments.
+ *
+ * @throws portfolio_caller_exception
+ */
+ public function load_data() {
+
+ $context = context_module::instance($this->cmid);
+
+ if (empty($this->fileid)) {
+ if (empty($this->sid) || empty($this->area)) {
+ throw new portfolio_caller_exception('invalidfileandsubmissionid', 'mod_assign');
+ }
+
+ }
+
+ // export either an area of files or a single file (see function for more detail)
+ // the first arg is an id or null. If it is an id, the rest of the args are ignored
+ // if it is null, the rest of the args are used to load a list of files from get_areafiles
+ $this->set_file_and_format_data($this->fileid, $context->id, $this->component, $this->area, $this->sid, 'timemodified', false);
+
+ }
+
+ /**
+ * prepares the package up before control is passed to the portfolio plugin.
+ *
+ * @throws portfolio_caller_exception
+ * @return mixed
+ */
+ public function prepare_package() {
+
+ if ($this->plugin && $this->editor) {
+ $options = portfolio_format_text_options();
+ $context = context_module::instance($this->cmid);
+ $options->context = $context;
+
+ $plugin = $this->get_submission_plugin();
+
+ $text = $plugin->get_editor_text($this->editor, $this->sid);
+ $format = $plugin->get_editor_format($this->editor, $this->sid);
+
+ $html = format_text($text, $format, $options);
+ $html = portfolio_rewrite_pluginfile_urls($html, $context->id, 'mod_assign', $this->area, $this->sid, $this->exporter->get('format'));
+
+ if (in_array($this->exporter->get('formatclass'), array(PORTFOLIO_FORMAT_PLAINHTML, PORTFOLIO_FORMAT_RICHHTML))) {
+ if ($files = $this->exporter->get('caller')->get('multifiles')) {
+ foreach ($files as $file) {
+ $this->exporter->copy_existing_file($file);
+ }
+ }
+ return $this->exporter->write_new_file($html, 'assignment.html', !empty($files));
+ } else if ($this->exporter->get('formatclass') == PORTFOLIO_FORMAT_LEAP2A) {
+ $leapwriter = $this->exporter->get('format')->leap2a_writer();
+ $entry = new portfolio_format_leap2a_entry($this->area . $this->cmid, print_context_name($context), 'resource', $html);
+
+ $entry->add_category('web', 'resource_type');
+ $entry->author = $this->user;
+ $leapwriter->add_entry($entry);
+ if ($files = $this->exporter->get('caller')->get('multifiles')) {
+ $leapwriter->link_files($entry, $files, $this->area . $this->cmid . 'file');
+ foreach ($files as $file) {
+ $this->exporter->copy_existing_file($file);
+ }
+ }
+ return $this->exporter->write_new_file($leapwriter->to_xml(), $this->exporter->get('format')->manifest_name(), true);
+ } else {
+ debugging('invalid format class: ' . $this->exporter->get('formatclass'));
+ }
+
+ }
+
+
+ if ($this->exporter->get('formatclass') == PORTFOLIO_FORMAT_LEAP2A) {
+ $leapwriter = $this->exporter->get('format')->leap2a_writer();
+ $files = array();
+ if ($this->singlefile) {
+ $files[] = $this->singlefile;
+ } elseif ($this->multifiles) {
+ $files = $this->multifiles;
+ } else {
+ throw new portfolio_caller_exception('invalidpreparepackagefile', 'portfolio', $this->get_return_url());
+ }
+
+ $entryids = array();
+ foreach ($files as $file) {
+ $entry = new portfolio_format_leap2a_file($file->get_filename(), $file);
+ $entry->author = $this->user;
+ $leapwriter->add_entry($entry);
+ $this->exporter->copy_existing_file($file);
+ $entryids[] = $entry->id;
+ }
+ if (count($files) > 1) {
+ $baseid = 'assign' . $this->cmid . $this->area;
+ $context = context_module::instance($this->cmid);
+
+ // if we have multiple files, they should be grouped together into a folder
+ $entry = new portfolio_format_leap2a_entry($baseid . 'group', print_context_name($context), 'selection');
+ $leapwriter->add_entry($entry);
+ $leapwriter->make_selection($entry, $entryids, 'Folder');
+ }
+ return $this->exporter->write_new_file($leapwriter->to_xml(), $this->exporter->get('format')->manifest_name(), true);
+ }
+ return $this->prepare_package_file();
+ }
+
+ /**
+ * fetch the plugin by its type
+ *
+ * @return assign_submission_plugin
+ */
+ private function get_submission_plugin() {
+ global $CFG;
+ if (!$this->plugin || !$this->cmid) {
+ return null;
+ }
+
+ require_once($CFG->dirroot . '/mod/assign/locallib.php');
+
+ $context = context_module::instance($this->cmid);
+
+ $assignment = new assign($context, null, null);
+ return $assignment->get_submission_plugin_by_type($this->plugin);
+ }
+
+ /**
+ * get sha1 file
+ * calculate a sha1 has of either a single file or a list
+ * of files based on the data set by load_data
+ *
+ * @return string
+ */
+ public function get_sha1() {
+
+ if ($this->plugin && $this->editor) {
+ $plugin = $this->get_submission_plugin();
+ $options = portfolio_format_text_options();
+ $options->context = context_module::instance($this->cmid);
+
+ $textsha1 = sha1(format_text($plugin->get_editor_text($this->editor, $this->sid),
+ $plugin->get_editor_format($this->editor, $this->sid), $options));
+ $filesha1 = '';
+ try {
+ $filesha1 = $this->get_sha1_file();
+ } catch (portfolio_caller_exception $e) {} // no files
+ return sha1($textsha1 . $filesha1);
+ }
+ return $this->get_sha1_file();
+ }
+
+ /**
+ * calculate the time to transfer either a single file or a list
+ * of files based on the data set by load_data
+ *
+ * @return int
+ */
+ public function expected_time() {
+ return $this->expected_time_file();
+ }
+
+ /**
+ * checking the permissions
+ *
+ * @return bool
+ */
+ public function check_permissions() {
+ $context = context_module::instance($this->cmid);
+ return has_capability('mod/assign:exportownsubmission', $context);
+ }
+
+ /**
+ * display a module name
+ *
+ * @return string
+ */
+ public static function display_name() {
+ return get_string('modulename', 'assign');
+ }
+
+ /**
+ * return array of formats supported by this portfolio call back
+ * @return array
+ */
+ public static function base_supported_formats() {
+
+ return array(PORTFOLIO_FORMAT_FILE, PORTFOLIO_FORMAT_LEAP2A);
+
+ }
+}
\ No newline at end of file
diff --git a/mod/assign/portfolio_callback.php b/mod/assign/portfolio_callback.php
deleted file mode 100644
index 71e6d820e5d78..0000000000000
--- a/mod/assign/portfolio_callback.php
+++ /dev/null
@@ -1,283 +0,0 @@
-.
-//
-// this file contains all the functions that aren't needed by core moodle
-// but start becoming required once we're actually inside the assignment module.
-
-/**
- * This file contains the callback class required by the portfolio api.
- *
- * @package mod_assign
- * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-/** Include assign locallib.php */
-require_once($CFG->dirroot . '/mod/assign/locallib.php');
-/** Include portfolio caller.php */
-require_once($CFG->libdir . '/portfolio/caller.php');
-
-/**
- * portfolio caller class for mod_assign.
- *
- * @package mod_assign
- * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class assign_portfolio_caller extends portfolio_module_caller_base {
-
-
- /** @var int callback arg - the id of submission we export */
- protected $sid;
-
- /** @var string component of the submission files we export*/
- protected $component;
-
- /** @var string callback arg - the area of submission files we export */
- protected $area;
-
- /** @var int callback arg - the id of file we export */
- protected $fileid;
-
- /** @var int callback arg - the cmid of the assignment we export */
- protected $cmid;
-
- /** @var string callback arg - the plugintype of the editor we export */
- protected $plugin;
-
- /** @var string callback arg - the name of the editor field we export */
- protected $editor;
-
- /**
- * callback arg for a single file export
- */
- public static function expected_callbackargs() {
- return array(
- 'cmid' => true,
- 'sid' => false,
- 'area' => false,
- 'component' => false,
- 'fileid' => false,
- 'plugin' => false,
- 'editor' => false,
- );
- }
-
- /**
- * the constructor
- * @param array $callbackargs
- */
- function __construct($callbackargs) {
- parent::__construct($callbackargs);
- $this->cm = get_coursemodule_from_id('assign', $this->cmid, 0, false, MUST_EXIST);
- }
-
- /**
- *
- * Load data needed for the portfolio export
- *
- * If the assignment type implements portfolio_load_data(), the processing is delegated
- * to it. Otherwise, the caller must provide either fileid (to export single file) or
- * submissionid and filearea (to export all data attached to the given submission file area) via callback arguments.
- *
- * @throws portfolio_caller_exception
- */
- public function load_data() {
-
- $context = context_module::instance($this->cmid);
-
- if (empty($this->fileid)) {
- if (empty($this->sid) || empty($this->area)) {
- throw new portfolio_caller_exception('invalidfileandsubmissionid', 'mod_assign');
- }
-
- }
-
- // export either an area of files or a single file (see function for more detail)
- // the first arg is an id or null. If it is an id, the rest of the args are ignored
- // if it is null, the rest of the args are used to load a list of files from get_areafiles
- $this->set_file_and_format_data($this->fileid, $context->id, $this->component, $this->area, $this->sid, 'timemodified', false);
-
- }
-
- /**
- * prepares the package up before control is passed to the portfolio plugin.
- *
- * @throws portfolio_caller_exception
- * @return mixed
- */
- public function prepare_package() {
-
- if ($this->plugin && $this->editor) {
- $options = portfolio_format_text_options();
- $context = context_module::instance($this->cmid);
- $options->context = $context;
-
- $plugin = $this->get_submission_plugin();
-
- $text = $plugin->get_editor_text($this->editor, $this->sid);
- $format = $plugin->get_editor_format($this->editor, $this->sid);
-
- $html = format_text($text, $format, $options);
- $html = portfolio_rewrite_pluginfile_urls($html, $context->id, 'mod_assign', $this->area, $this->sid, $this->exporter->get('format'));
-
- if (in_array($this->exporter->get('formatclass'), array(PORTFOLIO_FORMAT_PLAINHTML, PORTFOLIO_FORMAT_RICHHTML))) {
- if ($files = $this->exporter->get('caller')->get('multifiles')) {
- foreach ($files as $file) {
- $this->exporter->copy_existing_file($file);
- }
- }
- return $this->exporter->write_new_file($html, 'assignment.html', !empty($files));
- } else if ($this->exporter->get('formatclass') == PORTFOLIO_FORMAT_LEAP2A) {
- $leapwriter = $this->exporter->get('format')->leap2a_writer();
- $entry = new portfolio_format_leap2a_entry($this->area . $this->cmid, print_context_name($context), 'resource', $html);
-
- $entry->add_category('web', 'resource_type');
- $entry->author = $this->user;
- $leapwriter->add_entry($entry);
- if ($files = $this->exporter->get('caller')->get('multifiles')) {
- $leapwriter->link_files($entry, $files, $this->area . $this->cmid . 'file');
- foreach ($files as $file) {
- $this->exporter->copy_existing_file($file);
- }
- }
- return $this->exporter->write_new_file($leapwriter->to_xml(), $this->exporter->get('format')->manifest_name(), true);
- } else {
- debugging('invalid format class: ' . $this->exporter->get('formatclass'));
- }
-
- }
-
-
- if ($this->exporter->get('formatclass') == PORTFOLIO_FORMAT_LEAP2A) {
- $leapwriter = $this->exporter->get('format')->leap2a_writer();
- $files = array();
- if ($this->singlefile) {
- $files[] = $this->singlefile;
- } elseif ($this->multifiles) {
- $files = $this->multifiles;
- } else {
- throw new portfolio_caller_exception('invalidpreparepackagefile', 'portfolio', $this->get_return_url());
- }
-
- $entryids = array();
- foreach ($files as $file) {
- $entry = new portfolio_format_leap2a_file($file->get_filename(), $file);
- $entry->author = $this->user;
- $leapwriter->add_entry($entry);
- $this->exporter->copy_existing_file($file);
- $entryids[] = $entry->id;
- }
- if (count($files) > 1) {
- $baseid = 'assign' . $this->cmid . $this->area;
- $context = context_module::instance($this->cmid);
-
- // if we have multiple files, they should be grouped together into a folder
- $entry = new portfolio_format_leap2a_entry($baseid . 'group', print_context_name($context), 'selection');
- $leapwriter->add_entry($entry);
- $leapwriter->make_selection($entry, $entryids, 'Folder');
- }
- return $this->exporter->write_new_file($leapwriter->to_xml(), $this->exporter->get('format')->manifest_name(), true);
- }
- return $this->prepare_package_file();
- }
-
- /**
- * fetch the plugin by its type
- *
- * @return assign_submission_plugin
- */
- private function get_submission_plugin() {
- global $CFG;
- if (!$this->plugin || !$this->cmid) {
- return null;
- }
-
- require_once($CFG->dirroot . '/mod/assign/locallib.php');
-
- $context = context_module::instance($this->cmid);
-
- $assignment = new assign($context, null, null);
- return $assignment->get_submission_plugin_by_type($this->plugin);
- }
-
- /**
- * get sha1 file
- * calculate a sha1 has of either a single file or a list
- * of files based on the data set by load_data
- *
- * @return string
- */
- public function get_sha1() {
-
- if ($this->plugin && $this->editor) {
- $plugin = $this->get_submission_plugin();
- $options = portfolio_format_text_options();
- $options->context = context_module::instance($this->cmid);
-
- $textsha1 = sha1(format_text($plugin->get_editor_text($this->editor, $this->sid),
- $plugin->get_editor_format($this->editor, $this->sid), $options));
- $filesha1 = '';
- try {
- $filesha1 = $this->get_sha1_file();
- } catch (portfolio_caller_exception $e) {} // no files
- return sha1($textsha1 . $filesha1);
- }
- return $this->get_sha1_file();
- }
-
- /**
- * calculate the time to transfer either a single file or a list
- * of files based on the data set by load_data
- *
- * @return int
- */
- public function expected_time() {
- return $this->expected_time_file();
- }
-
- /**
- * checking the permissions
- *
- * @return bool
- */
- public function check_permissions() {
- $context = context_module::instance($this->cmid);
- return has_capability('mod/assign:exportownsubmission', $context);
- }
-
- /**
- * display a module name
- *
- * @return string
- */
- public static function display_name() {
- return get_string('modulename', 'assign');
- }
-
- /**
- * return array of formats supported by this portfolio call back
- * @return array
- */
- public static function base_supported_formats() {
-
- return array(PORTFOLIO_FORMAT_FILE, PORTFOLIO_FORMAT_LEAP2A);
-
- }
-}
-
diff --git a/mod/assign/renderable.php b/mod/assign/renderable.php
index 90b16bd6b520b..986f1da3e5a6d 100644
--- a/mod/assign/renderable.php
+++ b/mod/assign/renderable.php
@@ -547,7 +547,12 @@ public function __construct(context $context, $sid, $filearea, $component) {
require_once($CFG->libdir . '/portfoliolib.php');
if (count($files) >= 1 && has_capability('mod/assign:exportownsubmission', $this->context)) {
$button = new portfolio_add_button();
- $button->set_callback_options('assign_portfolio_caller', array('cmid' => $this->cm->id, 'sid'=>$sid, 'area'=>$filearea, 'component'=>$component), '/mod/assign/portfolio_callback.php');
+ $button->set_callback_options('assign_portfolio_caller',
+ array('cmid' => $this->cm->id,
+ 'sid' => $sid,
+ 'area' => $filearea,
+ 'component' => $component),
+ 'mod_assign');
$button->reset_formats();
$this->portfolioform = $button->to_html(PORTFOLIO_ADD_TEXT_LINK);
}
@@ -594,7 +599,9 @@ public function preprocess($dir, $filearea, $component) {
if (!empty($CFG->enableportfolios)) {
$button = new portfolio_add_button();
if (has_capability('mod/assign:exportownsubmission', $this->context)) {
- $button->set_callback_options('assign_portfolio_caller', array('cmid' => $this->cm->id, 'fileid' => $file->get_id()), '/mod/assign/portfolio_callback.php');
+ $button->set_callback_options('assign_portfolio_caller',
+ array('cmid' => $this->cm->id, 'fileid' => $file->get_id()),
+ 'mod_assign');
$button->set_format_by_file($file);
$file->portfoliobutton = $button->to_html(PORTFOLIO_ADD_ICON_LINK);
}
diff --git a/mod/assignment/lib.php b/mod/assignment/lib.php
index 33ce9bd24b47f..3198609b0ba49 100644
--- a/mod/assignment/lib.php
+++ b/mod/assignment/lib.php
@@ -2142,7 +2142,9 @@ function print_user_files($userid=0, $return=false) {
$path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/mod_assignment/submission/'.$submission->id.'/'.$filename);
$output .= ''.$OUTPUT->pix_icon(file_file_icon($file), get_mimetype_description($file), 'moodle', array('class' => 'icon')).s($filename).'';
if ($CFG->enableportfolios && $this->portfolio_exportable() && has_capability('mod/assignment:exportownsubmission', $this->context)) {
- $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'submissionid' => $submission->id, 'fileid' => $file->get_id()), '/mod/assignment/locallib.php');
+ $button->set_callback_options('assignment_portfolio_caller',
+ array('id' => $this->cm->id, 'submissionid' => $submission->id, 'fileid' => $file->get_id()),
+ 'mod_assignment');
$button->set_format_by_file($file);
$output .= $button->to_html(PORTFOLIO_ADD_ICON_LINK);
}
@@ -2154,7 +2156,9 @@ function print_user_files($userid=0, $return=false) {
}
}
if ($CFG->enableportfolios && count($files) > 1 && $this->portfolio_exportable() && has_capability('mod/assignment:exportownsubmission', $this->context)) {
- $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'submissionid' => $submission->id), '/mod/assignment/locallib.php');
+ $button->set_callback_options('assignment_portfolio_caller',
+ array('id' => $this->cm->id, 'submissionid' => $submission->id),
+ 'mod_assignment');
$output .= '
' . $button->to_html(PORTFOLIO_ADD_TEXT_LINK);
}
}
diff --git a/mod/assignment/renderer.php b/mod/assignment/renderer.php
index f514e7f75abad..6545edcf719e3 100644
--- a/mod/assignment/renderer.php
+++ b/mod/assignment/renderer.php
@@ -100,7 +100,7 @@ public function __construct($context, $itemid, $filearea='submission') {
$files = $fs->get_area_files($this->context->id, 'mod_assignment', $filearea, $itemid, "timemodified", false);
if (count($files) >= 1 && has_capability('mod/assignment:exportownsubmission', $this->context)) {
$button = new portfolio_add_button();
- $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'submissionid' => $itemid), '/mod/assignment/locallib.php');
+ $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'submissionid' => $itemid), 'mod_assignment');
$button->reset_formats();
$this->portfolioform = $button->to_html(PORTFOLIO_ADD_TEXT_LINK);
}
@@ -117,7 +117,7 @@ public function preprocess($dir, $filearea) {
if (!empty($CFG->enableportfolios)) {
$button = new portfolio_add_button();
if (has_capability('mod/assignment:exportownsubmission', $this->context)) {
- $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'fileid' => $file->get_id()), '/mod/assignment/locallib.php');
+ $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'fileid' => $file->get_id()), 'mod_assignment');
$button->set_format_by_file($file);
$file->portfoliobutton = $button->to_html(PORTFOLIO_ADD_ICON_LINK);
}
diff --git a/mod/assignment/type/online/assignment.class.php b/mod/assignment/type/online/assignment.class.php
index f3cd31be9abfd..a917d31eb4a4e 100644
--- a/mod/assignment/type/online/assignment.class.php
+++ b/mod/assignment/type/online/assignment.class.php
@@ -117,7 +117,7 @@ function view() {
if ($CFG->enableportfolios) {
require_once($CFG->libdir . '/portfoliolib.php');
$button = new portfolio_add_button();
- $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id), '/mod/assignment/locallib.php');
+ $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id), 'mod_assignment');
$fs = get_file_storage();
if ($files = $fs->get_area_files($this->context->id, 'mod_assignment', $this->filearea, $submission->id, "timemodified", false)) {
$button->set_formats(PORTFOLIO_FORMAT_RICHHTML);
diff --git a/mod/chat/report.php b/mod/chat/report.php
index 331cc964d2d35..35bd20288a935 100644
--- a/mod/chat/report.php
+++ b/mod/chat/report.php
@@ -113,7 +113,7 @@
'end' => $end,
);
$button = new portfolio_add_button();
- $button->set_callback_options('chat_portfolio_caller', $buttonoptions, '/mod/chat/locallib.php');
+ $button->set_callback_options('chat_portfolio_caller', $buttonoptions, 'mod_chat');
$button->render();
}
echo $OUTPUT->box_end();
@@ -239,7 +239,7 @@
'end' => $sessionend,
);
$button = new portfolio_add_button();
- $button->set_callback_options('chat_portfolio_caller', $buttonoptions, '/mod/chat/locallib.php');
+ $button->set_callback_options('chat_portfolio_caller', $buttonoptions, 'mod_chat');
$portfoliobutton = $button->to_html(PORTFOLIO_ADD_TEXT_LINK);
if (!empty($portfoliobutton)) {
echo '
' . $portfoliobutton;
@@ -265,7 +265,7 @@
if (!empty($CFG->enableportfolios) && $canexportsess) {
require_once($CFG->libdir . '/portfoliolib.php');
$button = new portfolio_add_button();
- $button->set_callback_options('chat_portfolio_caller', array('id' => $cm->id), '/mod/chat/locallib.php');
+ $button->set_callback_options('chat_portfolio_caller', array('id' => $cm->id), 'mod_chat');
$button->render(null, get_string('addalltoportfolio', 'portfolio'));
}
diff --git a/mod/data/lib.php b/mod/data/lib.php
index fb0dc5f052281..a1a47038afff9 100644
--- a/mod/data/lib.php
+++ b/mod/data/lib.php
@@ -1234,7 +1234,7 @@ function data_print_template($template, $records, $data, $search='', $page=0, $r
|| (data_isowner($record->id) && has_capability('mod/data:exportownentry', $context))))) {
require_once($CFG->libdir . '/portfoliolib.php');
$button = new portfolio_add_button();
- $button->set_callback_options('data_portfolio_caller', array('id' => $cm->id, 'recordid' => $record->id), '/mod/data/locallib.php');
+ $button->set_callback_options('data_portfolio_caller', array('id' => $cm->id, 'recordid' => $record->id), 'mod_data');
list($formats, $files) = data_portfolio_caller::formats($fields, $record);
$button->set_formats($formats);
$replacement[] = $button->to_html(PORTFOLIO_ADD_ICON_LINK);
diff --git a/mod/data/view.php b/mod/data/view.php
index 5220e04f16c56..65e512d8a68e5 100644
--- a/mod/data/view.php
+++ b/mod/data/view.php
@@ -760,7 +760,7 @@
if ($mode == '' && !empty($CFG->enableportfolios)) {
require_once($CFG->libdir . '/portfoliolib.php');
$button = new portfolio_add_button();
- $button->set_callback_options('data_portfolio_caller', array('id' => $cm->id), '/mod/data/locallib.php');
+ $button->set_callback_options('data_portfolio_caller', array('id' => $cm->id), 'mod_data');
if (data_portfolio_caller::has_files($data)) {
$button->set_formats(array(PORTFOLIO_FORMAT_RICHHTML, PORTFOLIO_FORMAT_LEAP2A)); // no plain html for us
}
diff --git a/mod/forum/discuss.php b/mod/forum/discuss.php
index efbb8df0457a7..774e7b0fe559b 100644
--- a/mod/forum/discuss.php
+++ b/mod/forum/discuss.php
@@ -192,7 +192,7 @@
if (!empty($CFG->enableportfolios) && has_capability('mod/forum:exportdiscussion', $modcontext)) {
require_once($CFG->libdir.'/portfoliolib.php');
$button = new portfolio_add_button();
- $button->set_callback_options('forum_portfolio_caller', array('discussionid' => $discussion->id), '/mod/forum/locallib.php');
+ $button->set_callback_options('forum_portfolio_caller', array('discussionid' => $discussion->id), 'mod_forum');
$button = $button->to_html(PORTFOLIO_ADD_FULL_FORM, get_string('exportdiscussion', 'mod_forum'));
$buttonextraclass = '';
if (empty($button)) {
diff --git a/mod/forum/lib.php b/mod/forum/lib.php
index d39ad0efb6b62..822e177e45045 100644
--- a/mod/forum/lib.php
+++ b/mod/forum/lib.php
@@ -3347,7 +3347,7 @@ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=fa
$p = array('postid' => $post->id);
require_once($CFG->libdir.'/portfoliolib.php');
$button = new portfolio_add_button();
- $button->set_callback_options('forum_portfolio_caller', array('postid' => $post->id), '/mod/forum/locallib.php');
+ $button->set_callback_options('forum_portfolio_caller', array('postid' => $post->id), 'mod_forum');
if (empty($attachments)) {
$button->set_formats(PORTFOLIO_FORMAT_PLAINHTML);
} else {
@@ -4001,7 +4001,7 @@ function forum_print_attachments($post, $cm, $type) {
$output .= "$iconimage ";
$output .= "".s($filename)."";
if ($canexport) {
- $button->set_callback_options('forum_portfolio_caller', array('postid' => $post->id, 'attachment' => $file->get_id()), '/mod/forum/locallib.php');
+ $button->set_callback_options('forum_portfolio_caller', array('postid' => $post->id, 'attachment' => $file->get_id()), 'mod_forum');
$button->set_format_by_file($file);
$output .= $button->to_html(PORTFOLIO_ADD_ICON_LINK);
}
@@ -4015,7 +4015,7 @@ function forum_print_attachments($post, $cm, $type) {
// Image attachments don't get printed as links
$imagereturn .= "
";
if ($canexport) {
- $button->set_callback_options('forum_portfolio_caller', array('postid' => $post->id, 'attachment' => $file->get_id()), '/mod/forum/locallib.php');
+ $button->set_callback_options('forum_portfolio_caller', array('postid' => $post->id, 'attachment' => $file->get_id()), 'mod_forum');
$button->set_format_by_file($file);
$imagereturn .= $button->to_html(PORTFOLIO_ADD_ICON_LINK);
}
@@ -4023,7 +4023,7 @@ function forum_print_attachments($post, $cm, $type) {
$output .= "$iconimage ";
$output .= format_text("".s($filename)."", FORMAT_HTML, array('context'=>$context));
if ($canexport) {
- $button->set_callback_options('forum_portfolio_caller', array('postid' => $post->id, 'attachment' => $file->get_id()), '/mod/forum/locallib.php');
+ $button->set_callback_options('forum_portfolio_caller', array('postid' => $post->id, 'attachment' => $file->get_id()), 'mod_forum');
$button->set_format_by_file($file);
$output .= $button->to_html(PORTFOLIO_ADD_ICON_LINK);
}
diff --git a/mod/glossary/export.php b/mod/glossary/export.php
index 773fd7f730721..8abcaea9b4629 100644
--- a/mod/glossary/export.php
+++ b/mod/glossary/export.php
@@ -70,7 +70,7 @@
if (!empty($CFG->enableportfolios) && $DB->count_records('glossary_entries', array('glossaryid' => $glossary->id))) {
require_once($CFG->libdir . '/portfoliolib.php');
$button = new portfolio_add_button();
- $button->set_callback_options('glossary_full_portfolio_caller', array('id' => $cm->id), '/mod/glossary/locallib.php');
+ $button->set_callback_options('glossary_full_portfolio_caller', array('id' => $cm->id), 'mod_glossary');
$button->render();
}
echo $OUTPUT->box_end();
diff --git a/mod/glossary/lib.php b/mod/glossary/lib.php
index 49f4c3fc16925..3c3f46379c588 100644
--- a/mod/glossary/lib.php
+++ b/mod/glossary/lib.php
@@ -1273,7 +1273,7 @@ function glossary_print_entry_icons($course, $cm, $glossary, $entry, $mode='',$h
if (!empty($CFG->enableportfolios) && (has_capability('mod/glossary:exportentry', $context) || ($iscurrentuser && has_capability('mod/glossary:exportownentry', $context)))) {
require_once($CFG->libdir . '/portfoliolib.php');
$button = new portfolio_add_button();
- $button->set_callback_options('glossary_entry_portfolio_caller', array('id' => $cm->id, 'entryid' => $entry->id), '/mod/glossary/locallib.php');
+ $button->set_callback_options('glossary_entry_portfolio_caller', array('id' => $cm->id, 'entryid' => $entry->id), 'mod_glossary');
$filecontext = $context;
if ($entry->sourceglossaryid == $cm->instance) {
diff --git a/portfolio/add.php b/portfolio/add.php
index 8cca63565bfe8..8a22e6fc60332 100644
--- a/portfolio/add.php
+++ b/portfolio/add.php
@@ -33,18 +33,18 @@
require_once($CFG->libdir . '/portfolio/caller.php');
require_once($CFG->libdir . '/portfolio/plugin.php');
-$dataid = optional_param('id', 0, PARAM_INT); // id of partially completed export. corresponds to a record in portfolio_tempdata
-$type = optional_param('type', null, PARAM_SAFEDIR); // if we're returning from an external system (postcontrol) for a single-export only plugin
-$cancel = optional_param('cancel', 0, PARAM_RAW); // user has cancelled the request
-$cancelsure = optional_param('cancelsure', 0, PARAM_BOOL); // make sure they confirm first
-$logreturn = optional_param('logreturn', 0, PARAM_BOOL); // when cancelling, we can also come from the log page, rather than the caller
-$instanceid = optional_param('instance', 0, PARAM_INT); // instanceof of configured portfolio plugin
-$courseid = optional_param('course', 0, PARAM_INT); // courseid the data being exported belongs to (caller object should provide this later)
-$stage = optional_param('stage', PORTFOLIO_STAGE_CONFIG, PARAM_INT); // stage of the export we're at (stored in the exporter)
-$postcontrol = optional_param('postcontrol', 0, PARAM_INT); // when returning from some bounce to an external system, this gets passed
-$callbackfile = optional_param('callbackfile', null, PARAM_PATH); // callback file eg /mod/forum/lib.php - the location of the exporting content
-$callbackclass = optional_param('callbackclass', null, PARAM_ALPHAEXT); // callback class eg forum_portfolio_caller - the class to handle the exporting content.
-$callerformats = optional_param('callerformats', null, PARAM_TAGLIST); // comma separated list of formats the specific place exporting content supports
+$dataid = optional_param('id', 0, PARAM_INT); // The ID of partially completed export, corresponds to a record in portfolio_tempdata.
+$type = optional_param('type', null, PARAM_SAFEDIR); // If we're returning from an external system (postcontrol) for a single-export only plugin.
+$cancel = optional_param('cancel', 0, PARAM_RAW); // User has cancelled the request.
+$cancelsure = optional_param('cancelsure', 0, PARAM_BOOL); // Make sure they confirm first.
+$logreturn = optional_param('logreturn', 0, PARAM_BOOL); // When cancelling, we can also come from the log page, rather than the caller.
+$instanceid = optional_param('instance', 0, PARAM_INT); // The instance of configured portfolio plugin.
+$courseid = optional_param('course', 0, PARAM_INT); // The courseid the data being exported belongs to (caller object should provide this later).
+$stage = optional_param('stage', PORTFOLIO_STAGE_CONFIG, PARAM_INT); // Stage of the export we're at (stored in the exporter).
+$postcontrol = optional_param('postcontrol', 0, PARAM_INT); // When returning from some bounce to an external system, this gets passed.
+$callbackcomponent = optional_param('callbackcomponent', null, PARAM_PATH); // Callback component eg mod_forum - the component of the exporting content.
+$callbackclass = optional_param('callbackclass', null, PARAM_ALPHAEXT); // Callback class eg forum_portfolio_caller - the class to handle the exporting content.
+$callerformats = optional_param('callerformats', null, PARAM_TAGLIST); // Comma separated list of formats the specific place exporting content supports.
require_login(); // this is selectively called again with $course later when we know for sure which one we're in.
$PAGE->set_context(get_system_context());
@@ -152,7 +152,7 @@
// we must be passed this from the caller, we cannot start a new export
// without knowing information about what part of moodle we come from.
- if (empty($callbackfile) || empty($callbackclass)) {
+ if (empty($callbackcomponent) || empty($callbackclass)) {
debugging('no callback file or class');
portfolio_exporter::print_expired_export();
}
@@ -173,13 +173,10 @@
$callbackargs[substr($key, 3)] = $value;
}
}
- // righto, now we have the callback args set up
- // load up the caller file and class and tell it to set up all the data
- // it needs
- require_once($CFG->dirroot . $callbackfile);
- if (!class_exists($callbackclass) || !is_subclass_of($callbackclass, 'portfolio_caller_base')) {
- throw new portfolio_caller_exception('callbackclassinvalid', 'portfolio');
- }
+
+ // Ensure that we found a file we can use, if not throw an exception.
+ portfolio_include_callback_file($callbackcomponent, $callbackclass);
+
$caller = new $callbackclass($callbackargs);
$caller->set('user', $USER);
if ($formats = explode(',', $callerformats)) {
@@ -194,7 +191,7 @@
portfolio_export_pagesetup($PAGE, $caller); // this calls require_login($course) if it can..
// finally! set up the exporter object with the portfolio instance, and caller information elements
- $exporter = new portfolio_exporter($instance, $caller, $callbackfile);
+ $exporter = new portfolio_exporter($instance, $caller, $callbackcomponent);
// set the export-specific variables, and save.
$exporter->set('user', $USER);
diff --git a/portfolio/upgrade.txt b/portfolio/upgrade.txt
index efc88ea345e6c..460df3dbe6ff4 100644
--- a/portfolio/upgrade.txt
+++ b/portfolio/upgrade.txt
@@ -7,3 +7,20 @@ required changes:
* The following methods must now be declared static for php5 compatibility:
- admin_config_form
- admin_config_validation
+
+=== 2.4 ===
+
+The set_callback_options function's third parameter has been changed from a file path
+to the component name - see MDL-33791. However, if any existing code passes a file path
+Moodle will attempt to obtain the component name from the file path provided. Also, the
+callback class should be located in the module's locallib.php file.
+
+Example of change:
+
+This:
+
+$button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'fileid' => $file->get_id()), '/mod/assignment/locallib.php');
+
+Now becomes:
+
+$button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'fileid' => $file->get_id()), 'mod_assignment');
\ No newline at end of file
diff --git a/user/portfoliologs.php b/user/portfoliologs.php
index d9f60355ebd67..1fa544b43deef 100644
--- a/user/portfoliologs.php
+++ b/user/portfoliologs.php
@@ -117,7 +117,13 @@
);
$logs = $DB->get_records('portfolio_log', array('userid' => $USER->id), 'time DESC', '*', ($page * $perpage), $perpage);
foreach ($logs as $log) {
- require_once($CFG->dirroot . $log->caller_file);
+ if (!empty($log->caller_file)) {
+ portfolio_include_callback_file($log->caller_file);
+ } else if (!empty($log->caller_component)) {
+ portfolio_include_callback_file($log->caller_component);
+ } else { // Errrmahgerrrd - this should never happen. Skipping.
+ continue;
+ }
$class = $log->caller_class;
$pluginname = '';
try {
diff --git a/version.php b/version.php
index b6cffad1e958a..6e7cade5b3950 100644
--- a/version.php
+++ b/version.php
@@ -30,7 +30,7 @@
defined('MOODLE_INTERNAL') || die();
-$version = 2012110700.00; // YYYYMMDD = weekly release date of this DEV branch
+$version = 2012110700.01; // YYYYMMDD = weekly release date of this DEV branch
// RR = release increments - 00 in DEV branches
// .XX = incremental changes