[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/admin/tool/lp/classes/form/ -> persistent.php (source)

   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   * Persistent form abstract.
  19   *
  20   * @package    tool_lp
  21   * @copyright  2015 Frédéric Massart - FMCorz.net
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace tool_lp\form;
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  use coding_exception;
  29  use moodleform;
  30  use stdClass;
  31  
  32  require_once($CFG->libdir.'/formslib.php');
  33  
  34  /**
  35   * Persistent form abstract class.
  36   *
  37   * This provides some shortcuts to validate objects based on the persistent model.
  38   *
  39   * Note that all mandatory fields (non-optional) of your model should be included in the
  40   * form definition. Mandatory fields which are not editable by the user should be
  41   * as hidden and constant.
  42   *
  43   *    $mform->addElement('hidden', 'userid');
  44   *    $mform->setType('userid', PARAM_INT);
  45   *    $mform->setConstant('userid', $this->_customdata['userid']);
  46   *
  47   * You may exclude some fields from the validation should your form include other
  48   * properties such as files. To do so use the $foreignfields property.
  49   *
  50   * @package    tool_lp
  51   * @copyright  2015 Frédéric Massart - FMCorz.net
  52   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  53   */
  54  abstract class persistent extends moodleform {
  55  
  56      /** @var string The fully qualified classname. */
  57      protected static $persistentclass = null;
  58  
  59      /** @var array Fields to remove when getting the final data. */
  60      protected static $fieldstoremove = array('submitbutton');
  61  
  62      /** @var array Fields to remove from the persistent validation. */
  63      protected static $foreignfields = array();
  64  
  65      /** @var \tool_lp\peristent Reference to the persistent. */
  66      private $persistent = null;
  67  
  68      /**
  69       * Constructor.
  70       *
  71       * The 'persistent' has to be passed as custom data when 'editing'.
  72       *
  73       * Note that in order for your persistent to be reloaded after form submission you should
  74       * either override the URL to include the ID to your resource, or add the ID to the form
  75       * fields.
  76       *
  77       * @param mixed $action
  78       * @param mixed $customdata
  79       * @param string $method
  80       * @param string $target
  81       * @param mixed $attributes
  82       * @param bool $editable
  83       */
  84      public function __construct($action = null, $customdata = null, $method = 'post', $target = '',
  85                                  $attributes = null, $editable = true) {
  86          if (empty(static::$persistentclass)) {
  87              throw new coding_exception('Static property $persistentclass must be set.');
  88          } else if (!is_subclass_of(static::$persistentclass, 'core_competency\\persistent')) {
  89              throw new coding_exception('Static property $persistentclass is not valid.');
  90          } else if (!array_key_exists('persistent', $customdata)) {
  91              throw new coding_exception('The custom data \'persistent\' key must be set, even if it is null.');
  92          }
  93  
  94          // Make a copy of the persistent passed, this ensures validation and object reference issues.
  95          $persistendata = new stdClass();
  96          $persistent = isset($customdata['persistent']) ? $customdata['persistent'] : null;
  97          if ($persistent) {
  98              if (!($persistent instanceof static::$persistentclass)) {
  99                  throw new coding_exception('Invalid persistent');
 100              }
 101              $persistendata = $persistent->to_record();
 102              unset($persistent);
 103          }
 104  
 105          $this->persistent = new static::$persistentclass();
 106          $this->persistent->from_record($persistendata);
 107  
 108          unset($customdata['persistent']);
 109          parent::__construct($action, $customdata, $method, $target, $attributes, $editable);
 110  
 111          // Load the defaults.
 112          $this->set_data($this->get_default_data());
 113      }
 114  
 115      /**
 116       * Convert some fields.
 117       *
 118       * @param  stdClass $data The whole data set.
 119       * @return stdClass The amended data set.
 120       */
 121      protected static function convert_fields(stdClass $data) {
 122          $class = static::$persistentclass;
 123          $properties = $class::get_formatted_properties();
 124  
 125          foreach ($data as $field => $value) {
 126              // Replace formatted properties.
 127              if (isset($properties[$field])) {
 128                  $formatfield = $properties[$field];
 129                  $data->$formatfield = $data->{$field}['format'];
 130                  $data->$field = $data->{$field}['text'];
 131              }
 132          }
 133  
 134          return $data;
 135      }
 136  
 137      /**
 138       * Define extra validation mechanims.
 139       *
 140       * The data here:
 141       * - does not include {@link self::$fieldstoremove}.
 142       * - does include {@link self::$foreignfields}.
 143       * - was converted to map persistent-like data, e.g. array $description to string $description + int $descriptionformat.
 144       *
 145       * You can modify the $errors parameter in order to remove some validation errors should you
 146       * need to. However, the best practice is to return new or overriden errors. Only modify the
 147       * errors passed by reference when you have no other option.
 148       *
 149       * Do not add any logic here, it is only intended to be used by child classes.
 150       *
 151       * @param  stdClass $data Data to validate.
 152       * @param  array $files Array of files.
 153       * @param  array $errors Currently reported errors.
 154       * @return array of additional errors, or overridden errors.
 155       */
 156      protected function extra_validation($data, $files, array &$errors) {
 157          return array();
 158      }
 159  
 160      /**
 161       * Filter out the foreign fields of the persistent.
 162       *
 163       * This can be overridden to filter out more complex fields.
 164       *
 165       * @param stdClass $data The data to filter the fields out of.
 166       * @return stdClass.
 167       */
 168      protected function filter_data_for_persistent($data) {
 169          return (object) array_diff_key((array) $data, array_flip((array) static::$foreignfields));
 170      }
 171  
 172      /**
 173       * Get the default data.
 174       *
 175       * This is the data that is prepopulated in the form at it loads, we automatically
 176       * fetch all the properties of the persistent however some needs to be converted
 177       * to map the form structure.
 178       *
 179       * Extend this class if you need to add more conversion.
 180       *
 181       * @return stdClass
 182       */
 183      protected function get_default_data() {
 184          $data = $this->get_persistent()->to_record();
 185          $class = static::$persistentclass;
 186          $properties = $class::get_formatted_properties();
 187  
 188          foreach ($data as $field => $value) {
 189              // Convert formatted properties.
 190              if (isset($properties[$field])) {
 191                  $data->$field = array(
 192                      'text' => $data->$field,
 193                      'format' => $data->{$properties[$field]}
 194                  );
 195                  unset($data->{$properties[$field]});
 196              }
 197          }
 198  
 199          return $data;
 200      }
 201  
 202      /**
 203       * Get form data.
 204       *
 205       * Conveniently removes non-desired properties and add the ID property.
 206       *
 207       * @return object|null
 208       */
 209      public function get_data() {
 210          $data = parent::get_data();
 211          if (is_object($data)) {
 212              foreach (static::$fieldstoremove as $field) {
 213                  unset($data->{$field});
 214              }
 215              $data = static::convert_fields($data);
 216  
 217              // Ensure that the ID is set.
 218              $data->id = $this->persistent->get_id();
 219          }
 220          return $data;
 221      }
 222  
 223      /**
 224       * Return the persistent object associated with this form instance.
 225       *
 226       * @return tool_lp\persistent
 227       */
 228      final protected function get_persistent() {
 229          return $this->persistent;
 230      }
 231  
 232      /**
 233       * Get the submitted form data.
 234       *
 235       * Conveniently removes non-desired properties.
 236       *
 237       * @return object|null
 238       */
 239      public function get_submitted_data() {
 240          $data = parent::get_submitted_data();
 241          if (is_object($data)) {
 242              foreach (static::$fieldstoremove as $field) {
 243                  unset($data->{$field});
 244              }
 245              $data = static::convert_fields($data);
 246          }
 247          return $data;
 248      }
 249  
 250      /**
 251       * Form validation.
 252       *
 253       * If you need extra validation, use {@link self::extra_validation()}.
 254       *
 255       * @param  array $data
 256       * @param  array $files
 257       * @return array
 258       */
 259      public final function validation($data, $files) {
 260          $errors = parent::validation($data, $files);
 261          $data = $this->get_submitted_data();
 262  
 263          // Only validate compatible fields.
 264          $persistentdata = $this->filter_data_for_persistent($data);
 265          $persistent = $this->get_persistent();
 266          $persistent->from_record((object) $persistentdata);
 267          $errors = array_merge($errors, $persistent->get_errors());
 268  
 269          // Apply extra validation.
 270          $extraerrors = $this->extra_validation($data, $files, $errors);
 271          $errors = array_merge($errors, (array) $extraerrors);
 272  
 273          return $errors;
 274      }
 275  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1