[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/grade/ -> grade_object.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   * Definition of a grade object class for grade item, grade category etc to inherit from
  19   *
  20   * @package   core_grades
  21   * @category  grade
  22   * @copyright 2006 Nicolas Connault
  23   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  /**
  29   * An abstract object that holds methods and attributes common to all grade_* objects defined here.
  30   *
  31   * @package   core_grades
  32   * @category  grade
  33   * @copyright 2006 Nicolas Connault
  34   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  abstract class grade_object {
  37      /**
  38       * The database table this grade object is stored in
  39       * @var string $table
  40       */
  41      public $table;
  42  
  43      /**
  44       * Array of required table fields, must start with 'id'.
  45       * @var array $required_fields
  46       */
  47      public $required_fields = array('id', 'timecreated', 'timemodified', 'hidden');
  48  
  49      /**
  50       * Array of optional fields with default values - usually long text information that is not always needed.
  51       * If you want to create an instance without optional fields use: new grade_object($only_required_fields, false);
  52       * @var array $optional_fields
  53       */
  54      public $optional_fields = array();
  55  
  56      /**
  57       * The PK.
  58       * @var int $id
  59       */
  60      public $id;
  61  
  62      /**
  63       * The first time this grade_object was created.
  64       * @var int $timecreated
  65       */
  66      public $timecreated;
  67  
  68      /**
  69       * The last time this grade_object was modified.
  70       * @var int $timemodified
  71       */
  72      public $timemodified;
  73  
  74      /**
  75       * 0 if visible, 1 always hidden or date not visible until
  76       * @var int $hidden
  77       */
  78      var $hidden = 0;
  79  
  80      /**
  81       * Constructor. Optionally (and by default) attempts to fetch corresponding row from the database
  82       *
  83       * @param array $params An array with required parameters for this grade object.
  84       * @param bool $fetch Whether to fetch corresponding row from the database or not,
  85       *        optional fields might not be defined if false used
  86       */
  87      public function __construct($params=NULL, $fetch=true) {
  88          if (!empty($params) and (is_array($params) or is_object($params))) {
  89              if ($fetch) {
  90                  if ($data = $this->fetch($params)) {
  91                      grade_object::set_properties($this, $data);
  92                  } else {
  93                      grade_object::set_properties($this, $this->optional_fields);//apply defaults for optional fields
  94                      grade_object::set_properties($this, $params);
  95                  }
  96  
  97              } else {
  98                  grade_object::set_properties($this, $params);
  99              }
 100  
 101          } else {
 102              grade_object::set_properties($this, $this->optional_fields);//apply defaults for optional fields
 103          }
 104      }
 105  
 106      /**
 107       * Makes sure all the optional fields are loaded.
 108       *
 109       * If id present, meaning the instance exists in the database, then data will be fetched from the database.
 110       * Defaults are used for new instances.
 111       */
 112      public function load_optional_fields() {
 113          global $DB;
 114          foreach ($this->optional_fields as $field=>$default) {
 115              if (property_exists($this, $field)) {
 116                  continue;
 117              }
 118              if (empty($this->id)) {
 119                  $this->$field = $default;
 120              } else {
 121                  $this->$field = $DB->get_field($this->table, $field, array('id', $this->id));
 122              }
 123          }
 124      }
 125  
 126      /**
 127       * Finds and returns a grade_object instance based on params.
 128       *
 129       * @static
 130       * @abstract
 131       * @param array $params associative arrays varname=>value
 132       * @return object grade_object instance or false if none found.
 133       */
 134      public static function fetch($params) {
 135          throw new coding_exception('fetch() method needs to be overridden in each subclass of grade_object');
 136      }
 137  
 138      /**
 139       * Finds and returns all grade_object instances based on $params.
 140       *
 141       * @static
 142       * @abstract
 143       * @throws coding_exception Throws a coding exception if fetch_all() has not been overriden by the grade object subclass
 144       * @param array $params Associative arrays varname=>value
 145       * @return array|bool Array of grade_object instances or false if none found.
 146       */
 147      public static function fetch_all($params) {
 148          throw new coding_exception('fetch_all() method needs to be overridden in each subclass of grade_object');
 149      }
 150  
 151      /**
 152       * Factory method which uses the parameters to retrieve matching instances from the database
 153       *
 154       * @param string $table The table to retrieve from
 155       * @param string $classname The name of the class to instantiate
 156       * @param array $params An array of conditions like $fieldname => $fieldvalue
 157       * @return mixed An object instance or false if not found
 158       */
 159      protected static function fetch_helper($table, $classname, $params) {
 160          if ($instances = grade_object::fetch_all_helper($table, $classname, $params)) {
 161              if (count($instances) > 1) {
 162                  // we should not tolerate any errors here - problems might appear later
 163                  print_error('morethanonerecordinfetch','debug');
 164              }
 165              return reset($instances);
 166          } else {
 167              return false;
 168          }
 169      }
 170  
 171      /**
 172       * Factory method which uses the parameters to retrieve all matching instances from the database
 173       *
 174       * @param string $table The table to retrieve from
 175       * @param string $classname The name of the class to instantiate
 176       * @param array $params An array of conditions like $fieldname => $fieldvalue
 177       * @return array|bool Array of object instances or false if not found
 178       */
 179      public static function fetch_all_helper($table, $classname, $params) {
 180          global $DB; // Need to introspect DB here.
 181  
 182          $instance = new $classname();
 183  
 184          $classvars = (array)$instance;
 185          $params    = (array)$params;
 186  
 187          $wheresql = array();
 188          $newparams = array();
 189  
 190          $columns = $DB->get_columns($table); // Cached, no worries.
 191  
 192          foreach ($params as $var=>$value) {
 193              if (!in_array($var, $instance->required_fields) and !array_key_exists($var, $instance->optional_fields)) {
 194                  continue;
 195              }
 196              if (!array_key_exists($var, $columns)) {
 197                  continue;
 198              }
 199              if (is_null($value)) {
 200                  $wheresql[] = " $var IS NULL ";
 201              } else {
 202                  if ($columns[$var]->meta_type === 'X') {
 203                      // We have a text/clob column, use the cross-db method for its comparison.
 204                      $wheresql[] = ' ' . $DB->sql_compare_text($var) . ' = ' . $DB->sql_compare_text('?') . ' ';
 205                  } else {
 206                      // Other columns (varchar, integers...).
 207                      $wheresql[] = " $var = ? ";
 208                  }
 209                  $newparams[] = $value;
 210              }
 211          }
 212  
 213          if (empty($wheresql)) {
 214              $wheresql = '';
 215          } else {
 216              $wheresql = implode("AND", $wheresql);
 217          }
 218  
 219          global $DB;
 220          $rs = $DB->get_recordset_select($table, $wheresql, $newparams);
 221          //returning false rather than empty array if nothing found
 222          if (!$rs->valid()) {
 223              $rs->close();
 224              return false;
 225          }
 226  
 227          $result = array();
 228          foreach($rs as $data) {
 229              $instance = new $classname();
 230              grade_object::set_properties($instance, $data);
 231              $result[$instance->id] = $instance;
 232          }
 233          $rs->close();
 234  
 235          return $result;
 236      }
 237  
 238      /**
 239       * Updates this object in the Database, based on its object variables. ID must be set.
 240       *
 241       * @param string $source from where was the object updated (mod/forum, manual, etc.)
 242       * @return bool success
 243       */
 244      public function update($source=null) {
 245          global $USER, $CFG, $DB;
 246  
 247          if (empty($this->id)) {
 248              debugging('Can not update grade object, no id!');
 249              return false;
 250          }
 251  
 252          $data = $this->get_record_data();
 253  
 254          $DB->update_record($this->table, $data);
 255  
 256          if (empty($CFG->disablegradehistory)) {
 257              unset($data->timecreated);
 258              $data->action       = GRADE_HISTORY_UPDATE;
 259              $data->oldid        = $this->id;
 260              $data->source       = $source;
 261              $data->timemodified = time();
 262              $data->loggeduser   = $USER->id;
 263              $DB->insert_record($this->table.'_history', $data);
 264          }
 265  
 266          $this->notify_changed(false);
 267          return true;
 268      }
 269  
 270      /**
 271       * Deletes this object from the database.
 272       *
 273       * @param string $source From where was the object deleted (mod/forum, manual, etc.)
 274       * @return bool success
 275       */
 276      public function delete($source=null) {
 277          global $USER, $CFG, $DB;
 278  
 279          if (empty($this->id)) {
 280              debugging('Can not delete grade object, no id!');
 281              return false;
 282          }
 283  
 284          $data = $this->get_record_data();
 285  
 286          if ($DB->delete_records($this->table, array('id'=>$this->id))) {
 287              if (empty($CFG->disablegradehistory)) {
 288                  unset($data->id);
 289                  unset($data->timecreated);
 290                  $data->action       = GRADE_HISTORY_DELETE;
 291                  $data->oldid        = $this->id;
 292                  $data->source       = $source;
 293                  $data->timemodified = time();
 294                  $data->loggeduser   = $USER->id;
 295                  $DB->insert_record($this->table.'_history', $data);
 296              }
 297              $this->notify_changed(true);
 298              return true;
 299  
 300          } else {
 301              return false;
 302          }
 303      }
 304  
 305      /**
 306       * Returns object with fields and values that are defined in database
 307       *
 308       * @return stdClass
 309       */
 310      public function get_record_data() {
 311          $data = new stdClass();
 312  
 313          foreach ($this as $var=>$value) {
 314              if (in_array($var, $this->required_fields) or array_key_exists($var, $this->optional_fields)) {
 315                  if (is_object($value) or is_array($value)) {
 316                      debugging("Incorrect property '$var' found when inserting grade object");
 317                  } else {
 318                      $data->$var = $value;
 319                  }
 320              }
 321          }
 322          return $data;
 323      }
 324  
 325      /**
 326       * Records this object in the Database, sets its id to the returned value, and returns that value.
 327       * If successful this function also fetches the new object data from database and stores it
 328       * in object properties.
 329       *
 330       * @param string $source From where was the object inserted (mod/forum, manual, etc.)
 331       * @return int The new grade object ID if successful, false otherwise
 332       */
 333      public function insert($source=null) {
 334          global $USER, $CFG, $DB;
 335  
 336          if (!empty($this->id)) {
 337              debugging("Grade object already exists!");
 338              return false;
 339          }
 340  
 341          $data = $this->get_record_data();
 342  
 343          $this->id = $DB->insert_record($this->table, $data);
 344  
 345          // set all object properties from real db data
 346          $this->update_from_db();
 347  
 348          $data = $this->get_record_data();
 349  
 350          if (empty($CFG->disablegradehistory)) {
 351              unset($data->timecreated);
 352              $data->action       = GRADE_HISTORY_INSERT;
 353              $data->oldid        = $this->id;
 354              $data->source       = $source;
 355              $data->timemodified = time();
 356              $data->loggeduser   = $USER->id;
 357              $DB->insert_record($this->table.'_history', $data);
 358          }
 359  
 360          $this->notify_changed(false);
 361          return $this->id;
 362      }
 363  
 364      /**
 365       * Using this object's id field, fetches the matching record in the DB, and looks at
 366       * each variable in turn. If the DB has different data, the db's data is used to update
 367       * the object. This is different from the update() function, which acts on the DB record
 368       * based on the object.
 369       *
 370       * @return bool True if successful
 371       */
 372      public function update_from_db() {
 373          if (empty($this->id)) {
 374              debugging("The object could not be used in its state to retrieve a matching record from the DB, because its id field is not set.");
 375              return false;
 376          }
 377          global $DB;
 378          if (!$params = $DB->get_record($this->table, array('id' => $this->id))) {
 379              debugging("Object with this id:{$this->id} does not exist in table:{$this->table}, can not update from db!");
 380              return false;
 381          }
 382  
 383          grade_object::set_properties($this, $params);
 384  
 385          return true;
 386      }
 387  
 388      /**
 389       * Given an associated array or object, cycles through each key/variable
 390       * and assigns the value to the corresponding variable in this object.
 391       *
 392       * @param stdClass $instance The object to set the properties on
 393       * @param array $params An array of properties to set like $propertyname => $propertyvalue
 394       * @return array|stdClass Either an associative array or an object containing property name, property value pairs
 395       */
 396      public static function set_properties(&$instance, $params) {
 397          $params = (array) $params;
 398          foreach ($params as $var => $value) {
 399              if (in_array($var, $instance->required_fields) or array_key_exists($var, $instance->optional_fields)) {
 400                  $instance->$var = $value;
 401              }
 402          }
 403      }
 404  
 405      /**
 406       * Called immediately after the object data has been inserted, updated, or
 407       * deleted in the database. Default does nothing, can be overridden to
 408       * hook in special behaviour.
 409       *
 410       * @param bool $deleted
 411       */
 412      protected function notify_changed($deleted) {
 413      }
 414  
 415      /**
 416       * Returns the current hidden state of this grade_item
 417       *
 418       * This depends on the grade object hidden setting and the current time if hidden is set to a "hidden until" timestamp
 419       *
 420       * @return bool Current hidden state
 421       */
 422      function is_hidden() {
 423          return ($this->hidden == 1 or ($this->hidden != 0 and $this->hidden > time()));
 424      }
 425  
 426      /**
 427       * Check grade object hidden status
 428       *
 429       * @return bool True if a "hidden until" timestamp is set, false if grade object is set to always visible or always hidden.
 430       */
 431      function is_hiddenuntil() {
 432          return $this->hidden > 1;
 433      }
 434  
 435      /**
 436       * Check a grade item hidden status.
 437       *
 438       * @return int 0 means visible, 1 hidden always, a timestamp means "hidden until"
 439       */
 440      function get_hidden() {
 441          return $this->hidden;
 442      }
 443  
 444      /**
 445       * Set a grade object hidden status
 446       *
 447       * @param int $hidden 0 means visiable, 1 means hidden always, a timestamp means "hidden until"
 448       * @param bool $cascade Ignored
 449       */
 450      function set_hidden($hidden, $cascade=false) {
 451          $this->hidden = $hidden;
 452          $this->update();
 453      }
 454  
 455      /**
 456       * Returns whether the grade object can control the visibility of the grades.
 457       *
 458       * @return bool
 459       */
 460      public function can_control_visibility() {
 461          return true;
 462      }
 463  }


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