| 1 | efrain | 1 | <?php
 | 
        
           |  |  | 2 | // This file is part of Moodle - http://moodle.org/
 | 
        
           |  |  | 3 | //
 | 
        
           |  |  | 4 | // Moodle is free software: you can redistribute it and/or modify
 | 
        
           |  |  | 5 | // it under the terms of the GNU General Public License as published by
 | 
        
           |  |  | 6 | // the Free Software Foundation, either version 3 of the License, or
 | 
        
           |  |  | 7 | // (at your option) any later version.
 | 
        
           |  |  | 8 | //
 | 
        
           |  |  | 9 | // Moodle is distributed in the hope that it will be useful,
 | 
        
           |  |  | 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
        
           |  |  | 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
        
           |  |  | 12 | // GNU General Public License for more details.
 | 
        
           |  |  | 13 | //
 | 
        
           |  |  | 14 | // You should have received a copy of the GNU General Public License
 | 
        
           |  |  | 15 | // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 | 
        
           |  |  | 16 |   | 
        
           |  |  | 17 | /**
 | 
        
           |  |  | 18 |  * This file contains the base classes that are extended to create portfolio export functionality.
 | 
        
           |  |  | 19 |  *
 | 
        
           |  |  | 20 |  * For places in moodle that want to add export functionality to subclass.
 | 
        
           |  |  | 21 |  *
 | 
        
           |  |  | 22 |  * @package core_portfolio
 | 
        
           |  |  | 23 |  * @copyright 2008 Penny Leach <penny@catalyst.net.nz>, Martin Dougiamas
 | 
        
           |  |  | 24 |  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 25 |  */
 | 
        
           |  |  | 26 |   | 
        
           |  |  | 27 | defined('MOODLE_INTERNAL') || die();
 | 
        
           |  |  | 28 |   | 
        
           |  |  | 29 | /**
 | 
        
           |  |  | 30 |  * Base class for callers
 | 
        
           |  |  | 31 |  *
 | 
        
           |  |  | 32 |  * @see also portfolio_module_caller_base
 | 
        
           |  |  | 33 |  *
 | 
        
           |  |  | 34 |  * @package core_portfolio
 | 
        
           |  |  | 35 |  * @category portfolio
 | 
        
           |  |  | 36 |  * @copyright 2008 Penny Leach <penny@catalyst.net.nz>
 | 
        
           |  |  | 37 |  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 38 |  */
 | 
        
           |  |  | 39 | abstract class portfolio_caller_base {
 | 
        
           |  |  | 40 |   | 
        
           |  |  | 41 |     /** @var stdClass course active during the call */
 | 
        
           |  |  | 42 |     protected $course;
 | 
        
           |  |  | 43 |   | 
        
           |  |  | 44 |     /** @var array configuration used for export. Use set_export_config and get_export_config to access */
 | 
        
           |  |  | 45 |     protected $exportconfig = array();
 | 
        
           |  |  | 46 |   | 
        
           |  |  | 47 |     /** @var stdclass user currently exporting content */
 | 
        
           |  |  | 48 |     protected $user;
 | 
        
           |  |  | 49 |   | 
        
           |  |  | 50 |     /** @var stdClass a reference to the exporter object */
 | 
        
           |  |  | 51 |     protected $exporter;
 | 
        
           |  |  | 52 |   | 
        
           |  |  | 53 |     /** @var array can be optionally overridden by subclass constructors */
 | 
        
           |  |  | 54 |     protected $supportedformats;
 | 
        
           |  |  | 55 |   | 
        
           |  |  | 56 |     /** @var stored_file single file exports configuration*/
 | 
        
           |  |  | 57 |     protected $singlefile;
 | 
        
           |  |  | 58 |   | 
        
           |  |  | 59 |     /** @var stored_file|object set this for multi file exports */
 | 
        
           |  |  | 60 |     protected $multifiles;
 | 
        
           |  |  | 61 |   | 
        
           |  |  | 62 |     /** @var string set this for generated-file exports */
 | 
        
           |  |  | 63 |     protected $intendedmimetype;
 | 
        
           |  |  | 64 |   | 
        
           |  |  | 65 |     /**
 | 
        
           |  |  | 66 |      * Create portfolio_caller object
 | 
        
           |  |  | 67 |      *
 | 
        
           |  |  | 68 |      * @param array $callbackargs argument properties
 | 
        
           |  |  | 69 |      */
 | 
        
           |  |  | 70 |     public function __construct($callbackargs) {
 | 
        
           |  |  | 71 |         $expected = call_user_func(array(get_class($this), 'expected_callbackargs'));
 | 
        
           |  |  | 72 |         foreach ($expected as $key => $required) {
 | 
        
           |  |  | 73 |             if (!array_key_exists($key, $callbackargs)) {
 | 
        
           |  |  | 74 |                 if ($required) {
 | 
        
           |  |  | 75 |                     $a = (object)array('arg' => $key, 'class' => get_class($this));
 | 
        
           |  |  | 76 |                     throw new portfolio_caller_exception('missingcallbackarg', 'portfolio', null, $a);
 | 
        
           |  |  | 77 |                 }
 | 
        
           |  |  | 78 |                 continue;
 | 
        
           |  |  | 79 |             }
 | 
        
           |  |  | 80 |             $this->{$key} = $callbackargs[$key];
 | 
        
           |  |  | 81 |         }
 | 
        
           |  |  | 82 |     }
 | 
        
           |  |  | 83 |   | 
        
           |  |  | 84 |     /**
 | 
        
           |  |  | 85 |      * If this caller wants any additional config items,
 | 
        
           |  |  | 86 |      * they should be defined here.
 | 
        
           |  |  | 87 |      *
 | 
        
           |  |  | 88 |      * @param moodleform $mform passed by reference, add elements to it.
 | 
        
           |  |  | 89 |      * @param portfolio_plugin_base $instance subclass of portfolio_plugin_base
 | 
        
           |  |  | 90 |      */
 | 
        
           |  |  | 91 |     public function export_config_form(&$mform, $instance) {}
 | 
        
           |  |  | 92 |   | 
        
           |  |  | 93 |   | 
        
           |  |  | 94 |     /**
 | 
        
           |  |  | 95 |      * Whether this caller wants any additional
 | 
        
           |  |  | 96 |      * config during export (eg options or metadata)
 | 
        
           |  |  | 97 |      *
 | 
        
           |  |  | 98 |      * @return bool
 | 
        
           |  |  | 99 |      */
 | 
        
           |  |  | 100 |     public function has_export_config() {
 | 
        
           |  |  | 101 |         return false;
 | 
        
           |  |  | 102 |     }
 | 
        
           |  |  | 103 |   | 
        
           |  |  | 104 |     /**
 | 
        
           |  |  | 105 |      * Just like the moodle form validation function,
 | 
        
           |  |  | 106 |      * this is passed in the data array from the form
 | 
        
           |  |  | 107 |      * and if a non empty array is returned, form processing will stop.
 | 
        
           |  |  | 108 |      *
 | 
        
           |  |  | 109 |      * @param array $data data from form.
 | 
        
           |  |  | 110 |      */
 | 
        
           |  |  | 111 |     public function export_config_validation($data) {}
 | 
        
           |  |  | 112 |   | 
        
           |  |  | 113 |     /**
 | 
        
           |  |  | 114 |      * How long does this reasonably expect to take..
 | 
        
           |  |  | 115 |      * Should we offer the user the option to wait..?
 | 
        
           |  |  | 116 |      * This is deliberately nonstatic so it can take filesize into account
 | 
        
           |  |  | 117 |      * the portfolio plugin can override this.
 | 
        
           |  |  | 118 |      * (so for example even if a huge file is being sent,
 | 
        
           |  |  | 119 |      * the download portfolio plugin doesn't care )
 | 
        
           |  |  | 120 |      */
 | 
        
           |  |  | 121 |     abstract public function expected_time();
 | 
        
           |  |  | 122 |   | 
        
           |  |  | 123 |     /**
 | 
        
           |  |  | 124 |      * Helper method to calculate expected time for multi or single file exports
 | 
        
           |  |  | 125 |      *
 | 
        
           |  |  | 126 |      * @return string file time expectation
 | 
        
           |  |  | 127 |      */
 | 
        
           |  |  | 128 |     public function expected_time_file() {
 | 
        
           |  |  | 129 |         if ($this->multifiles) {
 | 
        
           |  |  | 130 |             return portfolio_expected_time_file($this->multifiles);
 | 
        
           |  |  | 131 |         }
 | 
        
           |  |  | 132 |         else if ($this->singlefile) {
 | 
        
           |  |  | 133 |             return portfolio_expected_time_file($this->singlefile);
 | 
        
           |  |  | 134 |         }
 | 
        
           |  |  | 135 |         return PORTFOLIO_TIME_LOW;
 | 
        
           |  |  | 136 |     }
 | 
        
           |  |  | 137 |   | 
        
           |  |  | 138 |     /**
 | 
        
           |  |  | 139 |      * Function to build navigation
 | 
        
           |  |  | 140 |      */
 | 
        
           |  |  | 141 |     abstract public function get_navigation();
 | 
        
           |  |  | 142 |   | 
        
           |  |  | 143 |     /**
 | 
        
           |  |  | 144 |      * Helper function to get sha1
 | 
        
           |  |  | 145 |      */
 | 
        
           |  |  | 146 |     abstract public function get_sha1();
 | 
        
           |  |  | 147 |   | 
        
           |  |  | 148 |     /**
 | 
        
           |  |  | 149 |      * Helper function to calculate the sha1 for multi or single file exports
 | 
        
           |  |  | 150 |      *
 | 
        
           |  |  | 151 |      * @return string sha1 file exports
 | 
        
           |  |  | 152 |      */
 | 
        
           |  |  | 153 |     public function get_sha1_file() {
 | 
        
           |  |  | 154 |         if (empty($this->singlefile) && empty($this->multifiles)) {
 | 
        
           |  |  | 155 |             throw new portfolio_caller_exception('invalidsha1file', 'portfolio', $this->get_return_url());
 | 
        
           |  |  | 156 |         }
 | 
        
           |  |  | 157 |         if ($this->singlefile) {
 | 
        
           |  |  | 158 |             return $this->singlefile->get_contenthash();
 | 
        
           |  |  | 159 |         }
 | 
        
           |  |  | 160 |         $sha1s = array();
 | 
        
           |  |  | 161 |         foreach ($this->multifiles as $file) {
 | 
        
           |  |  | 162 |             $sha1s[] = $file->get_contenthash();
 | 
        
           |  |  | 163 |         }
 | 
        
           |  |  | 164 |         asort($sha1s);
 | 
        
           |  |  | 165 |         return sha1(implode('', $sha1s));
 | 
        
           |  |  | 166 |     }
 | 
        
           |  |  | 167 |   | 
        
           |  |  | 168 |     /**
 | 
        
           |  |  | 169 |      * Generic getter for properties belonging to this instance
 | 
        
           |  |  | 170 |      * <b>outside</b> the subclasses
 | 
        
           |  |  | 171 |      * like name, visible etc.
 | 
        
           |  |  | 172 |      *
 | 
        
           |  |  | 173 |      * @param string $field property's name
 | 
        
           |  |  | 174 |      * @return mixed
 | 
        
           |  |  | 175 |      * @throws portfolio_export_exception
 | 
        
           |  |  | 176 |      */
 | 
        
           |  |  | 177 |     public function get($field) {
 | 
        
           |  |  | 178 |         if (property_exists($this, $field)) {
 | 
        
           |  |  | 179 |             return $this->{$field};
 | 
        
           |  |  | 180 |         }
 | 
        
           |  |  | 181 |         $a = (object)array('property' => $field, 'class' => get_class($this));
 | 
        
           |  |  | 182 |         throw new portfolio_export_exception($this->get('exporter'), 'invalidproperty', 'portfolio', $this->get_return_url(), $a);
 | 
        
           |  |  | 183 |     }
 | 
        
           |  |  | 184 |   | 
        
           |  |  | 185 |     /**
 | 
        
           |  |  | 186 |      * Generic setter for properties belonging to this instance
 | 
        
           |  |  | 187 |      * <b>outside</b> the subclass
 | 
        
           |  |  | 188 |      * like name, visible, etc.
 | 
        
           |  |  | 189 |      *
 | 
        
           |  |  | 190 |      * @param string $field property's name
 | 
        
           |  |  | 191 |      * @param mixed $value property's value
 | 
        
           |  |  | 192 |      * @return bool
 | 
        
           |  |  | 193 |      * @throws moodle_exception
 | 
        
           |  |  | 194 |      */
 | 
        
           |  |  | 195 |     final public function set($field, &$value) {
 | 
        
           |  |  | 196 |         if (property_exists($this, $field)) {
 | 
        
           |  |  | 197 |             $this->{$field} =& $value;
 | 
        
           |  |  | 198 |             return true;
 | 
        
           |  |  | 199 |         }
 | 
        
           |  |  | 200 |         $a = (object)array('property' => $field, 'class' => get_class($this));
 | 
        
           |  |  | 201 |         throw new portfolio_export_exception($this->get('exporter'), 'invalidproperty', 'portfolio', $this->get_return_url(), $a);
 | 
        
           |  |  | 202 |     }
 | 
        
           |  |  | 203 |   | 
        
           |  |  | 204 |     /**
 | 
        
           |  |  | 205 |      * Stores the config generated at export time.
 | 
        
           |  |  | 206 |      * Subclasses can retrieve values using
 | 
        
           |  |  | 207 |      * @see get_export_config
 | 
        
           |  |  | 208 |      *
 | 
        
           |  |  | 209 |      * @param array $config formdata
 | 
        
           |  |  | 210 |      */
 | 
        
           |  |  | 211 |     final public function set_export_config($config) {
 | 
        
           |  |  | 212 |         $allowed = array_merge(
 | 
        
           |  |  | 213 |             array('wait', 'hidewait', 'format', 'hideformat'),
 | 
        
           |  |  | 214 |             $this->get_allowed_export_config()
 | 
        
           |  |  | 215 |         );
 | 
        
           |  |  | 216 |         foreach ($config as $key => $value) {
 | 
        
           |  |  | 217 |             if (!in_array($key, $allowed)) {
 | 
        
           |  |  | 218 |                 $a = (object)array('property' => $key, 'class' => get_class($this));
 | 
        
           |  |  | 219 |                 throw new portfolio_export_exception($this->get('exporter'), 'invalidexportproperty', 'portfolio', $this->get_return_url(), $a);
 | 
        
           |  |  | 220 |             }
 | 
        
           |  |  | 221 |             $this->exportconfig[$key] = $value;
 | 
        
           |  |  | 222 |         }
 | 
        
           |  |  | 223 |     }
 | 
        
           |  |  | 224 |   | 
        
           |  |  | 225 |     /**
 | 
        
           |  |  | 226 |      * Returns a particular export config value.
 | 
        
           |  |  | 227 |      * Subclasses shouldn't need to override this
 | 
        
           |  |  | 228 |      *
 | 
        
           |  |  | 229 |      * @param string $key the config item to fetch
 | 
        
           |  |  | 230 |      * @return null|mixed of export configuration
 | 
        
           |  |  | 231 |      */
 | 
        
           |  |  | 232 |     final public function get_export_config($key) {
 | 
        
           |  |  | 233 |         $allowed = array_merge(
 | 
        
           |  |  | 234 |             array('wait', 'hidewait', 'format', 'hideformat'),
 | 
        
           |  |  | 235 |             $this->get_allowed_export_config()
 | 
        
           |  |  | 236 |         );
 | 
        
           |  |  | 237 |         if (!in_array($key, $allowed)) {
 | 
        
           |  |  | 238 |             $a = (object)array('property' => $key, 'class' => get_class($this));
 | 
        
           |  |  | 239 |             throw new portfolio_export_exception($this->get('exporter'), 'invalidexportproperty', 'portfolio', $this->get_return_url(), $a);
 | 
        
           |  |  | 240 |         }
 | 
        
           |  |  | 241 |         if (!array_key_exists($key, $this->exportconfig)) {
 | 
        
           |  |  | 242 |             return null;
 | 
        
           |  |  | 243 |         }
 | 
        
           |  |  | 244 |         return $this->exportconfig[$key];
 | 
        
           |  |  | 245 |     }
 | 
        
           |  |  | 246 |   | 
        
           |  |  | 247 |     /**
 | 
        
           |  |  | 248 |      * Similar to the other allowed_config functions
 | 
        
           |  |  | 249 |      * if you need export config, you must provide
 | 
        
           |  |  | 250 |      * a list of what the fields are.
 | 
        
           |  |  | 251 |      * Even if you want to store stuff during export
 | 
        
           |  |  | 252 |      * without displaying a form to the user,
 | 
        
           |  |  | 253 |      * you can use this.
 | 
        
           |  |  | 254 |      *
 | 
        
           |  |  | 255 |      * @return array array of allowed keys
 | 
        
           |  |  | 256 |      */
 | 
        
           |  |  | 257 |     public function get_allowed_export_config() {
 | 
        
           |  |  | 258 |         return array();
 | 
        
           |  |  | 259 |     }
 | 
        
           |  |  | 260 |   | 
        
           |  |  | 261 |     /**
 | 
        
           |  |  | 262 |      * After the user submits their config,
 | 
        
           |  |  | 263 |      * they're given a confirm screen
 | 
        
           |  |  | 264 |      * summarising what they've chosen.
 | 
        
           |  |  | 265 |      * This function should return a table of nice strings => values
 | 
        
           |  |  | 266 |      * of what they've chosen
 | 
        
           |  |  | 267 |      * to be displayed in a table.
 | 
        
           |  |  | 268 |      *
 | 
        
           |  |  | 269 |      * @return bool
 | 
        
           |  |  | 270 |      */
 | 
        
           |  |  | 271 |     public function get_export_summary() {
 | 
        
           |  |  | 272 |         return false;
 | 
        
           |  |  | 273 |     }
 | 
        
           |  |  | 274 |   | 
        
           |  |  | 275 |     /**
 | 
        
           |  |  | 276 |      * Called before the portfolio plugin gets control.
 | 
        
           |  |  | 277 |      * This function should copy all the files it wants to
 | 
        
           |  |  | 278 |      * the temporary directory, using copy_existing_file
 | 
        
           |  |  | 279 |      * or write_new_file
 | 
        
           |  |  | 280 |      *
 | 
        
           |  |  | 281 |      * @see copy_existing_file()
 | 
        
           |  |  | 282 |      * @see write_new_file()
 | 
        
           |  |  | 283 |      */
 | 
        
           |  |  | 284 |     abstract public function prepare_package();
 | 
        
           |  |  | 285 |   | 
        
           |  |  | 286 |     /**
 | 
        
           |  |  | 287 |      * Helper function to copy files into the temp area
 | 
        
           |  |  | 288 |      * for single or multi file exports.
 | 
        
           |  |  | 289 |      *
 | 
        
           |  |  | 290 |      * @return stored_file|bool
 | 
        
           |  |  | 291 |      */
 | 
        
           |  |  | 292 |     public function prepare_package_file() {
 | 
        
           |  |  | 293 |         if (empty($this->singlefile) && empty($this->multifiles)) {
 | 
        
           |  |  | 294 |             throw new portfolio_caller_exception('invalidpreparepackagefile', 'portfolio', $this->get_return_url());
 | 
        
           |  |  | 295 |         }
 | 
        
           |  |  | 296 |         if ($this->singlefile) {
 | 
        
           |  |  | 297 |             return $this->exporter->copy_existing_file($this->singlefile);
 | 
        
           |  |  | 298 |         }
 | 
        
           |  |  | 299 |         foreach ($this->multifiles as $file) {
 | 
        
           |  |  | 300 |             $this->exporter->copy_existing_file($file);
 | 
        
           |  |  | 301 |         }
 | 
        
           |  |  | 302 |     }
 | 
        
           |  |  | 303 |   | 
        
           |  |  | 304 |     /**
 | 
        
           |  |  | 305 |      * Array of formats this caller supports.
 | 
        
           |  |  | 306 |      *
 | 
        
           |  |  | 307 |      * @return array list of formats
 | 
        
           |  |  | 308 |      */
 | 
        
           |  |  | 309 |     final public function supported_formats() {
 | 
        
           |  |  | 310 |         $basic = $this->base_supported_formats();
 | 
        
           |  |  | 311 |         if (empty($this->supportedformats)) {
 | 
        
           |  |  | 312 |             $specific = array();
 | 
        
           |  |  | 313 |         } else if (!is_array($this->supportedformats)) {
 | 
        
           |  |  | 314 |             debugging(get_class($this) . ' has set a non array value of member variable supported formats - working around but should be fixed in code');
 | 
        
           |  |  | 315 |             $specific = array($this->supportedformats);
 | 
        
           |  |  | 316 |         } else {
 | 
        
           |  |  | 317 |             $specific = $this->supportedformats;
 | 
        
           |  |  | 318 |         }
 | 
        
           |  |  | 319 |         return portfolio_most_specific_formats($specific, $basic);
 | 
        
           |  |  | 320 |     }
 | 
        
           |  |  | 321 |   | 
        
           |  |  | 322 |     /**
 | 
        
           |  |  | 323 |      * Base supported formats
 | 
        
           |  |  | 324 |      *
 | 
        
           |  |  | 325 |      * @throws coding_exception
 | 
        
           |  |  | 326 |      */
 | 
        
           |  |  | 327 |     public static function base_supported_formats() {
 | 
        
           |  |  | 328 |         throw new coding_exception('base_supported_formats() method needs to be overridden in each subclass of portfolio_caller_base');
 | 
        
           |  |  | 329 |     }
 | 
        
           |  |  | 330 |   | 
        
           |  |  | 331 |     /**
 | 
        
           |  |  | 332 |      * This is the "return to where you were" url
 | 
        
           |  |  | 333 |      */
 | 
        
           |  |  | 334 |     abstract public function get_return_url();
 | 
        
           |  |  | 335 |   | 
        
           |  |  | 336 |     /**
 | 
        
           |  |  | 337 |      * Callback to do whatever capability checks required
 | 
        
           |  |  | 338 |      * in the caller (called during the export process
 | 
        
           |  |  | 339 |      */
 | 
        
           |  |  | 340 |     abstract public function check_permissions();
 | 
        
           |  |  | 341 |   | 
        
           |  |  | 342 |     /**
 | 
        
           |  |  | 343 |      * Clean name to display to the user about this caller location
 | 
        
           |  |  | 344 |      */
 | 
        
           |  |  | 345 |     public static function display_name() {
 | 
        
           |  |  | 346 |         throw new coding_exception('display_name() method needs to be overridden in each subclass of portfolio_caller_base');
 | 
        
           |  |  | 347 |     }
 | 
        
           |  |  | 348 |   | 
        
           |  |  | 349 |     /**
 | 
        
           |  |  | 350 |      * Return a string to put at the header summarising this export.
 | 
        
           |  |  | 351 |      * By default, it just display the name (usually just 'assignment' or something unhelpful
 | 
        
           |  |  | 352 |      *
 | 
        
           |  |  | 353 |      * @return string
 | 
        
           |  |  | 354 |      */
 | 
        
           |  |  | 355 |     public function heading_summary() {
 | 
        
           |  |  | 356 |         return get_string('exportingcontentfrom', 'portfolio', $this->display_name());
 | 
        
           |  |  | 357 |     }
 | 
        
           |  |  | 358 |   | 
        
           |  |  | 359 |     /**
 | 
        
           |  |  | 360 |      * Load data
 | 
        
           |  |  | 361 |      */
 | 
        
           |  |  | 362 |     abstract public function load_data();
 | 
        
           |  |  | 363 |   | 
        
           |  |  | 364 |     /**
 | 
        
           |  |  | 365 |      * Set up the required files for this export.
 | 
        
           |  |  | 366 |      * This supports either passing files directly
 | 
        
           |  |  | 367 |      * or passing area arguments directly through
 | 
        
           |  |  | 368 |      * to the files api using file_storage::get_area_files
 | 
        
           |  |  | 369 |      *
 | 
        
           |  |  | 370 |      * @param mixed $ids one of:
 | 
        
           |  |  | 371 |      *                   - single file id
 | 
        
           |  |  | 372 |      *                   - single stored_file object
 | 
        
           |  |  | 373 |      *                   - array of file ids or stored_file objects
 | 
        
           |  |  | 374 |      *                   - null
 | 
        
           |  |  | 375 |      * @return void
 | 
        
           |  |  | 376 |      */
 | 
        
           |  |  | 377 |     public function set_file_and_format_data($ids=null /* ..pass arguments to area files here. */) {
 | 
        
           |  |  | 378 |         $args = func_get_args();
 | 
        
           |  |  | 379 |         array_shift($args); // shift off $ids
 | 
        
           |  |  | 380 |         if (empty($ids) && count($args) == 0) {
 | 
        
           |  |  | 381 |             return;
 | 
        
           |  |  | 382 |         }
 | 
        
           |  |  | 383 |         $files = array();
 | 
        
           |  |  | 384 |         $fs = get_file_storage();
 | 
        
           |  |  | 385 |         if (!empty($ids)) {
 | 
        
           |  |  | 386 |             if (is_numeric($ids) || $ids instanceof stored_file) {
 | 
        
           |  |  | 387 |                 $ids = array($ids);
 | 
        
           |  |  | 388 |             }
 | 
        
           |  |  | 389 |             foreach ($ids as $id) {
 | 
        
           |  |  | 390 |                 if ($id instanceof stored_file) {
 | 
        
           |  |  | 391 |                     $files[] = $id;
 | 
        
           |  |  | 392 |                 } else {
 | 
        
           |  |  | 393 |                     $files[] = $fs->get_file_by_id($id);
 | 
        
           |  |  | 394 |                 }
 | 
        
           |  |  | 395 |             }
 | 
        
           |  |  | 396 |         } else if (count($args) != 0) {
 | 
        
           |  |  | 397 |             if (count($args) < 4) {
 | 
        
           |  |  | 398 |                 throw new portfolio_caller_exception('invalidfileareaargs', 'portfolio');
 | 
        
           |  |  | 399 |             }
 | 
        
           |  |  | 400 |             $files = array_values(call_user_func_array(array($fs, 'get_area_files'), $args));
 | 
        
           |  |  | 401 |         }
 | 
        
           |  |  | 402 |         switch (count($files)) {
 | 
        
           |  |  | 403 |             case 0: return;
 | 
        
           |  |  | 404 |             case 1: {
 | 
        
           |  |  | 405 |                 $this->singlefile = $files[0];
 | 
        
           |  |  | 406 |                 return;
 | 
        
           |  |  | 407 |             }
 | 
        
           |  |  | 408 |             default: {
 | 
        
           |  |  | 409 |                 $this->multifiles = $files;
 | 
        
           |  |  | 410 |             }
 | 
        
           |  |  | 411 |         }
 | 
        
           |  |  | 412 |     }
 | 
        
           |  |  | 413 |   | 
        
           |  |  | 414 |     /**
 | 
        
           |  |  | 415 |      * The button-location always knows best
 | 
        
           |  |  | 416 |      * what the formats are... so it should be trusted.
 | 
        
           |  |  | 417 |      *
 | 
        
           |  |  | 418 |      * @todo MDL-31298 - re-analyze set_formats_from_button comment
 | 
        
           |  |  | 419 |      * @param array $formats array of PORTFOLIO_FORMAT_XX
 | 
        
           |  |  | 420 |      * @return void
 | 
        
           |  |  | 421 |      */
 | 
        
           |  |  | 422 |     public function set_formats_from_button($formats) {
 | 
        
           |  |  | 423 |         $base = $this->base_supported_formats();
 | 
        
           |  |  | 424 |         if (count($base) != count($formats)
 | 
        
           |  |  | 425 |                 || count($base) != count(array_intersect($base, $formats))) {
 | 
        
           |  |  | 426 |                 $this->supportedformats = portfolio_most_specific_formats($formats, $base);
 | 
        
           |  |  | 427 |                 return;
 | 
        
           |  |  | 428 |         }
 | 
        
           |  |  | 429 |         // in the case where the button hasn't actually set anything,
 | 
        
           |  |  | 430 |         // we need to run through again and resolve conflicts
 | 
        
           |  |  | 431 |         // TODO revisit this comment - it looks to me like it's lying
 | 
        
           |  |  | 432 |         $this->supportedformats = portfolio_most_specific_formats($formats, $formats);
 | 
        
           |  |  | 433 |     }
 | 
        
           |  |  | 434 |   | 
        
           |  |  | 435 |     /**
 | 
        
           |  |  | 436 |      * Adds a new format to the list of supported formats.
 | 
        
           |  |  | 437 |      * This functions also handles removing conflicting and less specific
 | 
        
           |  |  | 438 |      * formats at the same time.
 | 
        
           |  |  | 439 |      *
 | 
        
           |  |  | 440 |      * @param string $format one of PORTFOLIO_FORMAT_XX
 | 
        
           |  |  | 441 |      * @return void
 | 
        
           |  |  | 442 |      */
 | 
        
           |  |  | 443 |     protected function add_format($format) {
 | 
        
           |  |  | 444 |         if (in_array($format, $this->supportedformats)) {
 | 
        
           |  |  | 445 |             return;
 | 
        
           |  |  | 446 |         }
 | 
        
           |  |  | 447 |         $this->supportedformats = portfolio_most_specific_formats(array($format), $this->supportedformats);
 | 
        
           |  |  | 448 |     }
 | 
        
           |  |  | 449 |   | 
        
           |  |  | 450 |     /**
 | 
        
           |  |  | 451 |      * Gets mimetype
 | 
        
           |  |  | 452 |      *
 | 
        
           |  |  | 453 |      * @return string
 | 
        
           |  |  | 454 |      */
 | 
        
           |  |  | 455 |     public function get_mimetype() {
 | 
        
           |  |  | 456 |         if ($this->singlefile instanceof stored_file) {
 | 
        
           |  |  | 457 |             return $this->singlefile->get_mimetype();
 | 
        
           |  |  | 458 |         } else if (!empty($this->intendedmimetype)) {
 | 
        
           |  |  | 459 |             return $this->intendedmimetype;
 | 
        
           |  |  | 460 |         }
 | 
        
           |  |  | 461 |     }
 | 
        
           |  |  | 462 |   | 
        
           |  |  | 463 |     /**
 | 
        
           |  |  | 464 |      * Array of arguments the caller expects to be passed through to it.
 | 
        
           |  |  | 465 |      * This must be keyed on the argument name, and the array value is a boolean,
 | 
        
           |  |  | 466 |      * whether it is required, or just optional
 | 
        
           |  |  | 467 |      * eg array(
 | 
        
           |  |  | 468 |      *     id            => true,
 | 
        
           |  |  | 469 |      *     somethingelse => false
 | 
        
           |  |  | 470 |      * )
 | 
        
           |  |  | 471 |      */
 | 
        
           |  |  | 472 |     public static function expected_callbackargs() {
 | 
        
           |  |  | 473 |         throw new coding_exception('expected_callbackargs() method needs to be overridden in each subclass of portfolio_caller_base');
 | 
        
           |  |  | 474 |     }
 | 
        
           |  |  | 475 |   | 
        
           |  |  | 476 |   | 
        
           |  |  | 477 |     /**
 | 
        
           |  |  | 478 |      * Return the context for this export. used for $PAGE->set_context
 | 
        
           |  |  | 479 |      *
 | 
        
           |  |  | 480 |      * @param moodle_page $PAGE global page object
 | 
        
           |  |  | 481 |      */
 | 
        
           |  |  | 482 |     abstract public function set_context($PAGE);
 | 
        
           |  |  | 483 | }
 | 
        
           |  |  | 484 |   | 
        
           |  |  | 485 | /**
 | 
        
           |  |  | 486 |  * Base class for module callers.
 | 
        
           |  |  | 487 |  *
 | 
        
           |  |  | 488 |  * This just implements a few of the abstract functions
 | 
        
           |  |  | 489 |  * from portfolio_caller_base so that caller authors
 | 
        
           |  |  | 490 |  * don't need to.
 | 
        
           |  |  | 491 |  * @see also portfolio_caller_base
 | 
        
           |  |  | 492 |  *
 | 
        
           |  |  | 493 |  * @package core_portfolio
 | 
        
           |  |  | 494 |  * @category portfolio
 | 
        
           |  |  | 495 |  * @copyright 2008 Penny Leach <penny@catalyst.net.nz>
 | 
        
           |  |  | 496 |  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 497 |  */
 | 
        
           |  |  | 498 | abstract class portfolio_module_caller_base extends portfolio_caller_base {
 | 
        
           |  |  | 499 |   | 
        
           |  |  | 500 |     /** @var object coursemodule object. set this in the constructor like $this->cm = get_coursemodule_from_instance('forum', $this->forum->id); */
 | 
        
           |  |  | 501 |     protected $cm;
 | 
        
           |  |  | 502 |   | 
        
           |  |  | 503 |     /** @var int cmid */
 | 
        
           |  |  | 504 |     protected $id;
 | 
        
           |  |  | 505 |   | 
        
           |  |  | 506 |     /** @var stdclass course object */
 | 
        
           |  |  | 507 |     protected $course;
 | 
        
           |  |  | 508 |   | 
        
           |  |  | 509 |     /**
 | 
        
           |  |  | 510 |      * Navigation passed to print_header.
 | 
        
           |  |  | 511 |      * Override this to do something more specific than the module view page
 | 
        
           |  |  | 512 |      * like adding more links to the breadcrumb.
 | 
        
           |  |  | 513 |      *
 | 
        
           |  |  | 514 |      * @return array
 | 
        
           |  |  | 515 |      */
 | 
        
           |  |  | 516 |     public function get_navigation() {
 | 
        
           |  |  | 517 |         // No extra navigation by default, link to the course module already included.
 | 
        
           |  |  | 518 |         $extranav = array();
 | 
        
           |  |  | 519 |         return array($extranav, $this->cm);
 | 
        
           |  |  | 520 |     }
 | 
        
           |  |  | 521 |   | 
        
           |  |  | 522 |     /**
 | 
        
           |  |  | 523 |      * The url to return to after export or on cancel.
 | 
        
           |  |  | 524 |      * Defaults value is set to the module 'view' page.
 | 
        
           |  |  | 525 |      * Override this if it's deeper inside the module.
 | 
        
           |  |  | 526 |      *
 | 
        
           |  |  | 527 |      * @return string
 | 
        
           |  |  | 528 |      */
 | 
        
           |  |  | 529 |     public function get_return_url() {
 | 
        
           |  |  | 530 |         global $CFG;
 | 
        
           |  |  | 531 |         return $CFG->wwwroot . '/mod/' . $this->cm->modname . '/view.php?id=' . $this->cm->id;
 | 
        
           |  |  | 532 |     }
 | 
        
           |  |  | 533 |   | 
        
           |  |  | 534 |     /**
 | 
        
           |  |  | 535 |      * Override the parent get function
 | 
        
           |  |  | 536 |      * to make sure when we're asked for a course,
 | 
        
           |  |  | 537 |      * We retrieve the object from the database as needed.
 | 
        
           |  |  | 538 |      *
 | 
        
           |  |  | 539 |      * @param string $key the name of get function
 | 
        
           |  |  | 540 |      * @return stdClass
 | 
        
           |  |  | 541 |      */
 | 
        
           |  |  | 542 |     public function get($key) {
 | 
        
           |  |  | 543 |         if ($key != 'course') {
 | 
        
           |  |  | 544 |             return parent::get($key);
 | 
        
           |  |  | 545 |         }
 | 
        
           |  |  | 546 |         global $DB;
 | 
        
           |  |  | 547 |         if (empty($this->course)) {
 | 
        
           |  |  | 548 |             $this->course = $DB->get_record('course', array('id' => $this->cm->course));
 | 
        
           |  |  | 549 |         }
 | 
        
           |  |  | 550 |         return $this->course;
 | 
        
           |  |  | 551 |     }
 | 
        
           |  |  | 552 |   | 
        
           |  |  | 553 |     /**
 | 
        
           |  |  | 554 |      * Return a string to put at the header summarising this export.
 | 
        
           |  |  | 555 |      * by default, this function just display the name and module instance name.
 | 
        
           |  |  | 556 |      * Override this to do something more specific
 | 
        
           |  |  | 557 |      *
 | 
        
           |  |  | 558 |      * @return string
 | 
        
           |  |  | 559 |      */
 | 
        
           |  |  | 560 |     public function heading_summary() {
 | 
        
           |  |  | 561 |         return get_string('exportingcontentfrom', 'portfolio', $this->display_name() . ': ' . $this->cm->name);
 | 
        
           |  |  | 562 |     }
 | 
        
           |  |  | 563 |   | 
        
           |  |  | 564 |     /**
 | 
        
           |  |  | 565 |      * Overridden to return the course module context
 | 
        
           |  |  | 566 |      *
 | 
        
           |  |  | 567 |      * @param moodle_page $PAGE global PAGE
 | 
        
           |  |  | 568 |      */
 | 
        
           |  |  | 569 |     public function set_context($PAGE) {
 | 
        
           |  |  | 570 |         $PAGE->set_cm($this->cm);
 | 
        
           |  |  | 571 |     }
 | 
        
           |  |  | 572 | }
 |