mirror of
https://github.com/moodle/moodle.git
synced 2025-08-02 15:49:43 +02:00
MDL-16423 - refactor of portfolio_add_button into class for much better usability
currently portfolio_add_button still exists and just acts as a wrapper around the class so i have not changed any calling code to use the new objects yet.
This commit is contained in:
parent
7a8977d5fb
commit
ce09fecc99
3 changed files with 226 additions and 121 deletions
|
@ -56,6 +56,7 @@ $string['invalidproperty'] = 'Could not find that property ($a->property of $a->
|
|||
$string['invalidexportproperty'] = 'Could not find that export config property ($a->property of $a->class)';
|
||||
$string['invaliduserproperty'] = 'Could not find that user config property ($a->property of $a->class)';
|
||||
$string['invalidconfigproperty'] = 'Could not find that config property ($a->property of $a->class)';
|
||||
$string['invalidbuttonproperty'] = 'Could not find that property ($a) of portfolio_button';
|
||||
$string['manageportfolios'] = 'Manage portfolios';
|
||||
$string['manageyourportfolios'] = 'Manage your portfolios';
|
||||
$string['moderatefilesizethreshold'] = 'Moderate transfer filesize';
|
||||
|
@ -63,8 +64,10 @@ $string['moderatefilesizethresholddesc'] = 'Filesizes over this threshold will b
|
|||
$string['moderatedbsizethreshold'] = 'Moderate transfer dbsize';
|
||||
$string['moderatedbsizethresholddesc'] = 'Number of db records over which will be considered to take a moderate amount of time to transfer';
|
||||
$string['multipledisallowed'] = 'Trying to create another instance of a plugin that has disallowed multiple instances ($a)';
|
||||
$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['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['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';
|
||||
|
|
|
@ -78,4 +78,8 @@ class portfolio_caller_exception extends portfolio_exception {}
|
|||
*/
|
||||
class portfolio_plugin_exception extends portfolio_exception {}
|
||||
|
||||
/**
|
||||
* exception for interacting with the button class
|
||||
*/
|
||||
class portfolio_button_exception extends portfolio_exception {}
|
||||
?>
|
||||
|
|
|
@ -38,150 +38,248 @@ require_once($CFG->libdir . '/portfolio/plugin.php'); // the base classes f
|
|||
require_once($CFG->libdir . '/portfolio/caller.php'); // the base classes for calling code
|
||||
|
||||
/**
|
||||
* Entry point to add an 'add to portfolio' button to a page somewhere in moodle
|
||||
* use this to add a portfolio button or icon or form to a page
|
||||
*
|
||||
* This function does not check permissions. the caller must check permissions first.
|
||||
* These class methods do not check permissions. the caller must check permissions first.
|
||||
* Later, during the export process, the caller class is instantiated and the check_permissions method is called
|
||||
* This does <b>not</b> happen in this function - you are responsible for it.
|
||||
*
|
||||
* @param string $callbackclass name of the class containing the callback functions
|
||||
* activity modules should ALWAYS use their name_portfolio_caller
|
||||
* other locations must use something unique
|
||||
* @param mixed $callbackargs 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_NUMBER or PARAM_PATH
|
||||
* @param string $callbackfile this can be autodetected if it's in the same file as your caller,
|
||||
* but more 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'
|
||||
* @param int $format format to display the button or form or icon or link.
|
||||
* See constants PORTFOLIO_ADD_XXX for more info.
|
||||
* optional, defaults to PORTFOLI_ADD_FULL_FORM
|
||||
* @param str $addstr string to use for the button or icon alt text or link text.
|
||||
* this is whole string, not key. optional, defaults to 'Add to portfolio';
|
||||
* @param boolean $return whether to echo or return content (optional defaults to false (echo)
|
||||
* @param array $callersupports if the calling code knows better than the static method on the calling class (supported_formats)
|
||||
* eg, if there's a file that might be an image, you can pass it here instead
|
||||
* {@see portfolio_format_from_file} for how to get the appropriate formats to pass here.
|
||||
* 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'));
|
||||
*
|
||||
* or like this:
|
||||
* $button = new portfolio_add_button(array('callbackclass' => 'name_of_caller_class', 'callbackargs' => array('id' => 6), 'callbackfile' => '/your/mod/lib.php'));
|
||||
* $somehtml .= $button->to_html(PORTFOLIO_ADD_TEXT_LINK);
|
||||
*
|
||||
* See http://docs.moodle.org/en/Development:Adding_a_Portfolio_Button_to_a_page for more information
|
||||
*/
|
||||
function portfolio_add_button($callbackclass, $callbackargs, $callbackfile=null, $format=PORTFOLIO_ADD_FULL_FORM, $addstr=null, $return=false, $callersupports=null) {
|
||||
class portfolio_add_button {
|
||||
|
||||
global $SESSION, $CFG, $COURSE, $USER;
|
||||
private $callbackclass;
|
||||
private $callbackargs;
|
||||
private $callbackfile;
|
||||
private $formats;
|
||||
private $instances;
|
||||
|
||||
if (empty($CFG->enableportfolios)) {
|
||||
return;
|
||||
/**
|
||||
* constructor. either pass the options here or set them using the helper methods.
|
||||
* generally the code will be clearer if you use the helper methods.
|
||||
*
|
||||
* @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.
|
||||
* See set_callback_options for more information on these three.
|
||||
* key 'formats': an array of PORTFOLIO_FORMATS this caller will support
|
||||
* See set_formats for more information on this.
|
||||
*/
|
||||
public function __construct($options=null) {
|
||||
global $SESSION;
|
||||
if (isset($SESSION->portfolioexport)) {
|
||||
$a = new StdClass;
|
||||
$a->cancel = $CFG->wwwroot . '/portfolio/add.php?cancel=1';
|
||||
$a->finish = $CFG->wwwroot . '/portfolio/add.php?id=' . $SESSION->portfolioexport;
|
||||
throw new portfolio_button_exception('alreadyexporting', 'portfolio', null, $a);
|
||||
}
|
||||
if (empty($options)) {
|
||||
return true;
|
||||
}
|
||||
foreach ((array)$options as $key => $value) {
|
||||
if (!in_array($key, $constructoroptions)) {
|
||||
throw new portfolio_button_exception('invalidbuttonproperty', 'portfolio', $key);
|
||||
}
|
||||
$this->{$key} = $value;
|
||||
}
|
||||
$this->instances = portfolio_instances();
|
||||
}
|
||||
|
||||
if (!$instances = portfolio_instances()) {
|
||||
return;
|
||||
/*
|
||||
* @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 mixed $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_NUMBER 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'
|
||||
*/
|
||||
public function set_callback_options($class, array $argarray, $file=null) {
|
||||
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->dirroot . $file);
|
||||
if (!class_exists($class)) {
|
||||
throw new portfolio_button_exception('nocallbackclass', 'portfolio', $class);
|
||||
}
|
||||
$this->callbackclass = $class;
|
||||
$this->callbackargs = $argarray;
|
||||
}
|
||||
|
||||
if (defined('PORTFOLIO_INTERNAL')) {
|
||||
// something somewhere has detected a risk of this being called during inside the preparation
|
||||
// eg forum_print_attachments
|
||||
return;
|
||||
/*
|
||||
* @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.
|
||||
* {@see portfolio_format_from_file} for how to get the appropriate formats to pass here for uploaded files.
|
||||
*/
|
||||
public function set_formats($formats=null) {
|
||||
if (is_string($formats)) {
|
||||
$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'));
|
||||
}
|
||||
$this->formats = $formats;
|
||||
}
|
||||
|
||||
if (isset($SESSION->portfolioexport)) {
|
||||
$a = new StdClass;
|
||||
$a->cancel = $CFG->wwwroot . '/portfolio/add.php?cancel=1';
|
||||
$a->finish = $CFG->wwwroot . '/portfolio/add.php?id=' . $SESSION->portfolioexport;
|
||||
throw new portfolio_exception('alreadyexporting', 'portfolio', null, $a);
|
||||
/*
|
||||
* echo the form/button/icon/text link to the page
|
||||
*
|
||||
* @param int $format format to display the button or form or icon or link.
|
||||
* See constants PORTFOLIO_ADD_XXX for more info.
|
||||
* optional, defaults to PORTFOLI_ADD_FULL_FORM
|
||||
* @param str $addstr string to use for the button or icon alt text or link text.
|
||||
* this is whole string, not key. optional, defaults to 'Add to portfolio';
|
||||
*/
|
||||
public function render($format=null, $addstr=null) {
|
||||
echo $this->tohtml($format, $addstr);
|
||||
}
|
||||
|
||||
if (empty($callbackfile)) {
|
||||
$backtrace = debug_backtrace();
|
||||
if (!array_key_exists(0, $backtrace) || !array_key_exists('file', $backtrace[0]) || !is_readable($backtrace[0]['file'])) {
|
||||
debugging(get_string('nocallbackfile', 'portfolio'));
|
||||
/*
|
||||
* returns the form/button/icon/text link as html
|
||||
*
|
||||
* @param int $format format to display the button or form or icon or link.
|
||||
* See constants PORTFOLIO_ADD_XXX for more info.
|
||||
* optional, defaults to PORTFOLI_ADD_FULL_FORM
|
||||
* @param str $addstr string to use for the button or icon alt text or link text.
|
||||
* this is whole string, not key. optional, defaults to 'Add to portfolio';
|
||||
*/
|
||||
public function to_html($format=null, $addstr=null) {
|
||||
global $CFG, $COURSE;
|
||||
if (!$this->is_renderable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$callbackfile = substr($backtrace[0]['file'], strlen($CFG->dirroot));
|
||||
} else {
|
||||
if (!is_readable($CFG->dirroot . $callbackfile)) {
|
||||
debugging(get_string('nocallbackfile', 'portfolio'));
|
||||
return;
|
||||
if (empty($this->callbackclass) || $this->callbackfile) {
|
||||
throw new portfolio_button_exception('mustcallsetcallbackoptions', 'portfolio');
|
||||
}
|
||||
}
|
||||
|
||||
require_once($CFG->dirroot . $callbackfile);
|
||||
|
||||
if (empty($callersupports)) {
|
||||
$callersupports = call_user_func(array($callbackclass, 'supported_formats'));
|
||||
}
|
||||
|
||||
$formoutput = '<form method="post" action="' . $CFG->wwwroot . '/portfolio/add.php" id="portfolio-add-button">' . "\n";
|
||||
$linkoutput = '<a href="' . $CFG->wwwroot . '/portfolio/add.php?';
|
||||
foreach ($callbackargs as $key => $value) {
|
||||
if (!empty($value) && !is_string($value) && !is_numeric($value)) {
|
||||
$a->key = $key;
|
||||
$a->value = print_r($value, true);
|
||||
debugging(get_string('nonprimative', 'portfolio', $a));
|
||||
return;
|
||||
if (empty($this->formats)) {
|
||||
// use the caller defaults
|
||||
$this->set_formats();
|
||||
}
|
||||
$linkoutput .= 'ca_' . $key . '=' . $value . '&';
|
||||
$formoutput .= "\n" . '<input type="hidden" name="ca_' . $key . '" value="' . $value . '" />';
|
||||
}
|
||||
$formoutput .= "\n" . '<input type="hidden" name="callbackfile" value="' . $callbackfile . '" />';
|
||||
$formoutput .= "\n" . '<input type="hidden" name="callbackclass" value="' . $callbackclass . '" />';
|
||||
$formoutput .= "\n" . '<input type="hidden" name="course" value="' . (!empty($COURSE) ? $COURSE->id : 0) . '" />';
|
||||
$linkoutput .= 'callbackfile=' . $callbackfile . '&callbackclass='
|
||||
. $callbackclass . '&course=' . (!empty($COURSE) ? $COURSE->id : 0);
|
||||
$selectoutput = '';
|
||||
if (count($instances) == 1) {
|
||||
$instance = array_shift($instances);
|
||||
$formats = portfolio_supported_formats_intersect($callersupports, $instance->supported_formats());
|
||||
if (count($formats) == 0) {
|
||||
// bail. no common formats.
|
||||
debugging(get_string('nocommonformats', 'portfolio', $callbackclass));
|
||||
return;
|
||||
$formoutput = '<form method="post" action="' . $CFG->wwwroot . '/portfolio/add.php" id="portfolio-add-button">' . "\n";
|
||||
$linkoutput = '<a href="' . $CFG->wwwroot . '/portfolio/add.php?';
|
||||
foreach ($this->callbackargs as $key => $value) {
|
||||
if (!empty($value) && !is_string($value) && !is_numeric($value)) {
|
||||
$a->key = $key;
|
||||
$a->value = print_r($value, true);
|
||||
debugging(get_string('nonprimative', 'portfolio', $a));
|
||||
return;
|
||||
}
|
||||
$linkoutput .= 'ca_' . $key . '=' . $value . '&';
|
||||
$formoutput .= "\n" . '<input type="hidden" name="ca_' . $key . '" value="' . $value . '" />';
|
||||
}
|
||||
if ($error = portfolio_instance_sanity_check($instance)) {
|
||||
// bail, plugin is misconfigured
|
||||
debugging(get_string('instancemisconfigured', 'portfolio', get_string($error[$instance->get('id')], 'portfolio_' . $instance->get('plugin'))));
|
||||
return;
|
||||
$formoutput .= "\n" . '<input type="hidden" name="callbackfile" value="' . $this->callbackfile . '" />';
|
||||
$formoutput .= "\n" . '<input type="hidden" name="callbackclass" value="' . $this->callbackclass . '" />';
|
||||
$formoutput .= "\n" . '<input type="hidden" name="course" value="' . (!empty($COURSE) ? $COURSE->id : 0) . '" />';
|
||||
$linkoutput .= 'callbackfile=' . $this->callbackfile . '&callbackclass='
|
||||
. $this->callbackclass . '&course=' . (!empty($COURSE) ? $COURSE->id : 0);
|
||||
$selectoutput = '';
|
||||
if (count($this->instances) == 1) {
|
||||
$instance = array_shift($this->instances);
|
||||
$formats = portfolio_supported_formats_intersect($this->formats, $instance->supported_formats());
|
||||
if (count($formats) == 0) {
|
||||
// bail. no common formats.
|
||||
debugging(get_string('nocommonformats', 'portfolio', $this->callbackclass));
|
||||
return;
|
||||
}
|
||||
if ($error = portfolio_instance_sanity_check($instance)) {
|
||||
// bail, plugin is misconfigured
|
||||
debugging(get_string('instancemisconfigured', 'portfolio', get_string($error[$instance->get('id')], 'portfolio_' . $instance->get('plugin'))));
|
||||
return;
|
||||
}
|
||||
$formoutput .= "\n" . '<input type="hidden" name="instance" value="' . $instance->get('id') . '" />';
|
||||
$linkoutput .= '&instance=' . $instance->get('id');
|
||||
}
|
||||
else {
|
||||
$selectoutput = portfolio_instance_select($this->instances, $this->formats, $this->callbackclass, 'instance', true);
|
||||
}
|
||||
$formoutput .= "\n" . '<input type="hidden" name="instance" value="' . $instance->get('id') . '" />';
|
||||
$linkoutput .= '&instance=' . $instance->get('id');
|
||||
}
|
||||
else {
|
||||
$selectoutput = portfolio_instance_select($instances, $callersupports, $callbackclass, 'instance', true);
|
||||
}
|
||||
|
||||
if (empty($addstr)) {
|
||||
$addstr = get_string('addtoportfolio', 'portfolio');
|
||||
}
|
||||
if (empty($format)) {
|
||||
$format = PORTFOLIO_ADD_FULL_FORM;
|
||||
}
|
||||
switch ($format) {
|
||||
case PORTFOLIO_ADD_FULL_FORM:
|
||||
$formoutput .= $selectoutput;
|
||||
$formoutput .= "\n" . '<input type="submit" value="' . $addstr .'" />';
|
||||
$formoutput .= "\n" . '</form>';
|
||||
break;
|
||||
case PORTFOLIO_ADD_ICON_FORM:
|
||||
$formoutput .= $selectoutput;
|
||||
$formoutput .= "\n" . '<input type="image" src="' . $CFG->pixpath . '/t/portfolio.gif" alt=' . $addstr .'" />';
|
||||
$formoutput .= "\n" . '</form>';
|
||||
break;
|
||||
case PORTFOLIO_ADD_ICON_LINK:
|
||||
$linkoutput .= '"><img src="' . $CFG->pixpath . '/t/portfolio.gif" alt=' . $addstr .'" /></a>';
|
||||
break;
|
||||
case PORTFOLIO_ADD_TEXT_LINK:
|
||||
$linkoutput .= '">' . $addstr .'</a>';
|
||||
break;
|
||||
default:
|
||||
debugging(get_string('invalidaddformat', 'portfolio', $format));
|
||||
}
|
||||
$output = (in_array($format, array(PORTFOLIO_ADD_FULL_FORM, PORTFOLIO_ADD_ICON_FORM)) ? $formoutput : $linkoutput);
|
||||
if ($return) {
|
||||
if (empty($addstr)) {
|
||||
$addstr = get_string('addtoportfolio', 'portfolio');
|
||||
}
|
||||
if (empty($format)) {
|
||||
$format = PORTFOLIO_ADD_FULL_FORM;
|
||||
}
|
||||
switch ($format) {
|
||||
case PORTFOLIO_ADD_FULL_FORM:
|
||||
$formoutput .= $selectoutput;
|
||||
$formoutput .= "\n" . '<input type="submit" value="' . $addstr .'" />';
|
||||
$formoutput .= "\n" . '</form>';
|
||||
break;
|
||||
case PORTFOLIO_ADD_ICON_FORM:
|
||||
$formoutput .= $selectoutput;
|
||||
$formoutput .= "\n" . '<input type="image" src="' . $CFG->pixpath . '/t/portfolio.gif" alt=' . $addstr .'" />';
|
||||
$formoutput .= "\n" . '</form>';
|
||||
break;
|
||||
case PORTFOLIO_ADD_ICON_LINK:
|
||||
$linkoutput .= '"><img src="' . $CFG->pixpath . '/t/portfolio.gif" alt=' . $addstr .'" /></a>';
|
||||
break;
|
||||
case PORTFOLIO_ADD_TEXT_LINK:
|
||||
$linkoutput .= '">' . $addstr .'</a>';
|
||||
break;
|
||||
default:
|
||||
debugging(get_string('invalidaddformat', 'portfolio', $format));
|
||||
}
|
||||
$output = (in_array($format, array(PORTFOLIO_ADD_FULL_FORM, PORTFOLIO_ADD_ICON_FORM)) ? $formoutput : $linkoutput);
|
||||
return $output;
|
||||
} else {
|
||||
echo $output;
|
||||
}
|
||||
return true;
|
||||
|
||||
/**
|
||||
* does some internal checks
|
||||
* these are not errors, just situations
|
||||
* where it's not appropriate to add the button
|
||||
*/
|
||||
private function is_renderable() {
|
||||
global $CFG;
|
||||
if (empty($CFG->enableportfolios)) {
|
||||
return false;
|
||||
}
|
||||
if (defined('PORTFOLIO_INTERNAL')) {
|
||||
// something somewhere has detected a risk of this being called during inside the preparation
|
||||
// eg forum_print_attachments
|
||||
return false;
|
||||
}
|
||||
if (!$this->instances) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function portfolio_add_button($callbackclass, $callbackargs, $callbackfile=null, $format=PORTFOLIO_ADD_FULL_FORM, $addstr=null, $return=false, $callersupports=null) {
|
||||
$button = new portfolio_add_button();
|
||||
$button->set_callback_options($callbackclass, $callbackargs, $callbackfile);
|
||||
$button->set_formats($callersupports);
|
||||
if ($return) {
|
||||
return $button->to_html($format, $addstr);
|
||||
}
|
||||
$button->render();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue