]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-16423 - refactor of portfolio_add_button into class for much better usability
authormjollnir_ <mjollnir_>
Wed, 10 Sep 2008 16:34:08 +0000 (16:34 +0000)
committermjollnir_ <mjollnir_>
Wed, 10 Sep 2008 16:34:08 +0000 (16:34 +0000)
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.

lang/en_utf8/portfolio.php
lib/portfolio/exceptions.php
lib/portfoliolib.php

index cc327a670227bc265506e06187b0bae00786834f..f3040f4e7f5157038d0083f7f79185d55faa471d 100644 (file)
@@ -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';
index aad25ac3b8975807fab2db8dcb4750262f130c6d..52476b25d7b57fe0071e8dc3c5814454e606be60 100644 (file)
@@ -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 {}
 ?>
index 1850b8a0ccf53c45dabc6b3e3971a6b5b4bc84e4..c39b7700acd5d2e61c6dd9ee3c2bd4a6ed702849 100644 (file)
@@ -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) {
-
-    global $SESSION, $CFG, $COURSE, $USER;
-
-    if (empty($CFG->enableportfolios)) {
-        return;
-    }
-
-    if (!$instances = portfolio_instances()) {
-        return;
-    }
-
-    if (defined('PORTFOLIO_INTERNAL')) {
-        // something somewhere has detected a risk of this being called during inside the preparation
-        // eg forum_print_attachments
-        return;
-    }
-
-    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);
-    }
-
-    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'));
-            return;
+class portfolio_add_button {
+
+    private $callbackclass;
+    private $callbackargs;
+    private $callbackfile;
+    private $formats;
+    private $instances;
+
+    /**
+    * 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();
+    }
+
+    /*
+    * @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');
+            }
 
-        $callbackfile = substr($backtrace[0]['file'], strlen($CFG->dirroot));
-    } else {
-        if (!is_readable($CFG->dirroot . $callbackfile)) {
-            debugging(get_string('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;
+    }
+
+    /*
+    * @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;
+    }
+
+    /*
+    * 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);
+    }
+
+    /*
+    * 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;
         }
-    }
-
-    require_once($CFG->dirroot . $callbackfile);
+        if (empty($this->callbackclass) || $this->callbackfile) {
+            throw new portfolio_button_exception('mustcallsetcallbackoptions', 'portfolio');
+        }
+        if (empty($this->formats)) {
+            // use the caller defaults
+            $this->set_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 ($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 . '&amp;';
+            $formoutput .= "\n" . '<input type="hidden" name="ca_' . $key . '" value="' . $value . '" />';
+        }
+        $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 . '&amp;callbackclass='
+            . $this->callbackclass . '&amp;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 .= '&amp;instance=' . $instance->get('id');
+        }
+        else {
+            $selectoutput = portfolio_instance_select($this->instances, $this->formats, $this->callbackclass, 'instance', true);
+        }
 
-    if (empty($callersupports)) {
-        $callersupports = call_user_func(array($callbackclass, 'supported_formats'));
+        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;
     }
 
-    $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;
+    /**
+    * 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;
         }
-        $linkoutput .= 'ca_' . $key . '=' . $value . '&amp;';
-        $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 . '&amp;callbackclass='
-        . $callbackclass . '&amp;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;
+        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 ($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;
+        if (!$this->instances) {
+            return false;
         }
-        $formoutput .= "\n" . '<input type="hidden" name="instance" value="' . $instance->get('id') . '" />';
-        $linkoutput .= '&amp;instance=' . $instance->get('id');
+        return true;
     }
-    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);
+}
+
+
+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 $output;
-    } else {
-        echo $output;
+        return $button->to_html($format, $addstr);
     }
-    return true;
+    $button->render();
 }
 
 /**