Adding a Portfolio Button to a page: Difference between revisions
Penny Leach (talk | contribs) |
Penny Leach (talk | contribs) |
||
Line 115: | Line 115: | ||
$this->assignment = unserialize(serialize($this->assignment)); | $this->assignment = unserialize(serialize($this->assignment)); | ||
} | } | ||
===reliance on large data and atomicity=== | |||
For more information on this see [[http://tracker.moodle.org/browse/MDL-15934|MDL-15934] - if you need to work with large amounts of data for the export (eg, whole database module instance, or whole glossary) you don't want to store it in the session in between calculating the sha1 (during the user interactive bit) and actually sending the data (can be in cron). Use set_export_data and get_export_data instead (provided by the parent class). |
Revision as of 13:41, 5 August 2008
Introduction
Adding an 'Add to Portfolio' button to any page is relatively trivial, there are just two things that you need to do:
Write a subclass
You can either subclass portfolio_caller_base for the general case, or portfolio_module_caller_base if you're somewhere inside mod/
This sounds scary, but really it's not! It's a very small class. portfolio_caller_base has abstract functions that you must override, and some functions that you can override if you want to do something special. You should call it something like $module_portfolio_caller, or in a more complicated case (say assignment/type/upload, assignment_upload_portfolio_caller)
If you're adding the portfolio button somewhere in a module, it's better to subclass portfolio_module_caller_base, which implements 2 of the below abstract methods for you.
Methods you must override
__construct
When your object is constructed, the contents of whatever callback arguments you passed to portfolio_add_button are passed back to you here in an array, so your chance to set member variables or do whatever you need is in the constructor.
During the export screens, it's desirable to still have some sensible navigation that logically follows from the place the user was before they started the export process. This function should return components to pass to build_nagivation (extralinks and cm). portfolio_module_caller_base implements this for you
prepare_package
prepares the package up before control is passed to the portfolio plugin. You should copy any files (or write out any files) into the temporary directory provided, where they'll be found by the portfolio plugin.
expected_time
You should return a constant here to indicate how long the transfer is expected to take. This should be based on the size of the file. There are three options, PORTFOLIO_TIME_LOW, PORTFOLIO_TIME_MODERATE, and PORTFOLIO_TIME_HIGH. The first means the user will not be asked if they want to wait for the transfer or not, they will just wait. The second and third mean they'll be given the option (and in the case of the third, advised not to). The portfolio plugin can override this if it wants (eg in the case of download, they always want to wait for the transfer)
check_permissions
portfolio/add.php will expect the caller to verify the user is allowed to export the given content. This function should perform any has_capability checks it needs to and return a booelan.
get_return_url
This is used for redirecting the user on the case of a cancelled export, or at the end of their export, they are offered the option of continuing back to where they were (what this function returns) or on to their portfolio. portfolio_module_caller_base implements this for you (but will use mod/modname/view.php)
display_name (static)
A nice language string for displaying the location of this export to the user (this is used to notify the user in case of duplicate exports that originated from different places in moodle (Eg exporting an assignment upload and a forum post attachment that are the same file)
get_sha1
Return a sha1 of the content being exported - used to detect duplicate exports later.
Methods you can override
supported_formats (static)
The formats this caller can support. At export time, both the plugin and the caller are polled for which formats they can support, and then the intersection is used to determine the export format. In the case that the intersection is greater than 1, the user is asked for their selection.
The available formats you can choose from are in portfolio_supported_formats and are constants PORTFOLIO_FORMAT_XXX. By default, the subclass defines PORTFOLIO_FORMAT_FILE.
has_export_config
If there's any addition config during the export process (for example, extra metadata), you can override this function to return true. If you do this, you must also override export_config_form and get_export_summary.
export_config_form
This function is called, and passed a moodle form object by reference to add elements to it. TODO: it would be nice to able to add validation at this point too.
export_config_validation
This follows the exact same format as the validation() function in the moodleform object.
get_allowed_export_config
If at any point, your caller is going to use set_export_config, you must implement this function to return an array of allowed config fields. (Note that you can set export time config even if you're not using interactive user config)
get_export_summary
If your plugin has overridden has_export_config, you must implement this to display nicely to the user on the confirmation screen. It should return a named array (keys are nice strings to describe the config, values are the config options)
Call portfolio_add_button in the appropriate place
Now that you've implemented this class, you just need to add the button. To do this, you require_once("$CFG->libdir/portfoliolib.php"); and call portfolio_add_button. It takes the following parameters:
$callbackclass
The name of the class you've made that subclassed portfolio_caller_base.
$callbackargs
An associative array of key=>value pairs you want passed to the constructor of your class. These must be primitives, as they are added as hidden form fields and cleaned to either PARAM_ALPHAEXT, PARAM_NUMERIC or PARAM_PATH. Weird stuff will happen if they're not compliant.
$callbackfile
This can be autodetected from the backtrace of where this function was called, but if your class definition isn't in the same file as the caller (eg if your caller is some .php script, but the class is in a lib.php file), you can pass it explicitly here.
$fullform
whether you want the full form with the dropmenu of available plugins or just a little icon. defaults to true. (using the icon will force a whole screen on the wizard)
$return
Whether you want the output returned or echoed. Defaults to false (echo)
A few extra notes on the caller base class
protected $course
There is a protected member variable, $course, that subclasses can set (with $this->set('course', $course); ).
portfolio_add_button tries to look for a course object at the point that it's called, by doing a global $COURSE which is hackish but mostly works. This is also used to build the navigation during the export process. If for some reason, your navigation doesn't include the current course, you can set it like this. You shouldn't need to in the majority of cases.
serialization
The caller object is stored in the user's session during the export process. In Moodle, session_start is called very early on, before the class definition is loaded. The portfolio/add.php and associated libraries work around this by loading the class definitions and then serializing and unserializing the objects again. However, if you're storing any real objects in your caller class, you will need to do this as well. See the assignment implementation for how this done (using php5's __wakeup function):
public function __wakeup() { require_once($this->assignmentfile); $this->assignment = unserialize(serialize($this->assignment)); }
reliance on large data and atomicity
For more information on this see [[https://tracker.moodle.org/browse/MDL-15934 MDL-15934] - if you need to work with large amounts of data for the export (eg, whole database module instance, or whole glossary) you don't want to store it in the session in between calculating the sha1 (during the user interactive bit) and actually sending the data (can be in cron). Use set_export_data and get_export_data instead (provided by the parent class).