[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
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 * Course completion critieria aggregation 19 * 20 * @package core_completion 21 * @category completion 22 * @copyright 2009 Catalyst IT Ltd 23 * @author Aaron Barnes <[email protected]> 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 30 /** 31 * Trigger for the new data_object api. 32 * 33 * See data_object::__constructor 34 */ 35 define('DATA_OBJECT_FETCH_BY_KEY', 2); 36 37 /** 38 * A data abstraction object that holds methods and attributes 39 * 40 * @package core_completion 41 * @category completion 42 * @copyright 2009 Catalyst IT Ltd 43 * @author Aaron Barnes <[email protected]> 44 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 45 */ 46 abstract class data_object { 47 48 /* @var string Table that the class maps to in the database */ 49 public $table; 50 51 /* @var array Array of required table fields, must start with 'id'. */ 52 public $required_fields = array('id'); 53 54 /** 55 * Array of optional fields with default values - usually long text information that is not always needed. 56 * If you want to create an instance without optional fields use: new data_object($only_required_fields, false); 57 * @var array 58 */ 59 public $optional_fields = array(); 60 61 /* @var Array of unique fields, used in where clauses and constructor */ 62 public $unique_fields = array(); 63 64 /* @var int The primary key */ 65 public $id; 66 67 68 /** 69 * Constructor. Optionally (and by default) attempts to fetch corresponding row from DB. 70 * 71 * If $fetch is not false, there are a few different things that can happen: 72 * - true: 73 * load corresponding row from the database, using $params as the WHERE clause 74 * 75 * - DATA_OBJECT_FETCH_BY_KEY: 76 * load corresponding row from the database, using only the $id in the WHERE clause (if set), 77 * otherwise using the columns listed in $this->unique_fields. 78 * 79 * - array(): 80 * load corresponding row from the database, using the columns listed in this array 81 * in the WHERE clause 82 * 83 * @param array $params required parameters and their values for this data object 84 * @param mixed $fetch if false, do not attempt to fetch from the database, otherwise see notes 85 */ 86 public function __construct($params = null, $fetch = true) { 87 88 if (is_object($params)) { 89 throw new coding_exception('data_object params should be in the form of an array, not an object'); 90 } 91 92 // If no params given, apply defaults for optional fields 93 if (empty($params) || !is_array($params)) { 94 self::set_properties($this, $this->optional_fields); 95 return; 96 } 97 98 // If fetch is false, do not load from database 99 if ($fetch === false) { 100 self::set_properties($this, $params); 101 return; 102 } 103 104 // Compose where clause only from fields in unique_fields 105 if ($fetch === DATA_OBJECT_FETCH_BY_KEY && !empty($this->unique_fields)) { 106 if (empty($params['id'])) { 107 $where = array_intersect_key($params, array_flip($this->unique_fields)); 108 } 109 else { 110 $where = array('id' => $params['id']); 111 } 112 // Compose where clause from given field names 113 } else if (is_array($fetch) && !empty($fetch)) { 114 $where = array_intersect_key($params, array_flip($fetch)); 115 // Use entire params array for where clause 116 } else { 117 $where = $params; 118 } 119 120 // Attempt to load from database 121 if ($data = $this->fetch($where)) { 122 // Apply data from database, then data sent to constructor 123 self::set_properties($this, $data); 124 self::set_properties($this, $params); 125 } else { 126 // Apply defaults for optional fields, then data from constructor 127 self::set_properties($this, $this->optional_fields); 128 self::set_properties($this, $params); 129 } 130 } 131 132 /** 133 * Makes sure all the optional fields are loaded. 134 * 135 * If id present (==instance exists in db) fetches data from db. 136 * Defaults are used for new instances. 137 */ 138 public function load_optional_fields() { 139 global $DB; 140 foreach ($this->optional_fields as $field=>$default) { 141 if (property_exists($this, $field)) { 142 continue; 143 } 144 if (empty($this->id)) { 145 $this->$field = $default; 146 } else { 147 $this->$field = $DB->get_field($this->table, $field, array('id', $this->id)); 148 } 149 } 150 } 151 152 /** 153 * Finds and returns a data_object instance based on params. 154 * 155 * This function MUST be overridden by all deriving classes. 156 * 157 * @param array $params associative arrays varname => value 158 * @throws coding_exception This function MUST be overridden 159 * @return data_object instance of data_object or false if none found. 160 */ 161 public static function fetch($params) { 162 throw new coding_exception('fetch() method needs to be overridden in each subclass of data_object'); 163 } 164 165 /** 166 * Finds and returns all data_object instances based on params. 167 * 168 * This function MUST be overridden by all deriving classes. 169 * 170 * @param array $params associative arrays varname => value 171 * @throws coding_exception This function MUST be overridden 172 * @return array array of data_object instances or false if none found. 173 */ 174 public static function fetch_all($params) { 175 throw new coding_exception('fetch_all() method needs to be overridden in each subclass of data_object'); 176 } 177 178 /** 179 * Factory method - uses the parameters to retrieve matching instance from the DB. 180 * 181 * @final 182 * @param string $table The table name to fetch from 183 * @param string $classname The class that you want the result instantiated as 184 * @param array $params Any params required to select the desired row 185 * @return object Instance of $classname or false. 186 */ 187 protected static function fetch_helper($table, $classname, $params) { 188 if ($instances = self::fetch_all_helper($table, $classname, $params)) { 189 if (count($instances) > 1) { 190 // we should not tolerate any errors here - problems might appear later 191 print_error('morethanonerecordinfetch','debug'); 192 } 193 return reset($instances); 194 } else { 195 return false; 196 } 197 } 198 199 /** 200 * Factory method - uses the parameters to retrieve all matching instances from the DB. 201 * 202 * @final 203 * @param string $table The table name to fetch from 204 * @param string $classname The class that you want the result instantiated as 205 * @param array $params Any params required to select the desired row 206 * @return mixed array of object instances or false if not found 207 */ 208 public static function fetch_all_helper($table, $classname, $params) { 209 $instance = new $classname(); 210 211 $classvars = (array)$instance; 212 $params = (array)$params; 213 214 $wheresql = array(); 215 216 foreach ($params as $var=>$value) { 217 if (!in_array($var, $instance->required_fields) and !array_key_exists($var, $instance->optional_fields)) { 218 continue; 219 } 220 if (is_null($value)) { 221 $wheresql[] = " $var IS NULL "; 222 } else { 223 $wheresql[] = " $var = ? "; 224 $params[] = $value; 225 } 226 } 227 228 if (empty($wheresql)) { 229 $wheresql = ''; 230 } else { 231 $wheresql = implode("AND", $wheresql); 232 } 233 234 global $DB; 235 if ($datas = $DB->get_records_select($table, $wheresql, $params)) { 236 237 $result = array(); 238 foreach($datas as $data) { 239 $instance = new $classname(); 240 self::set_properties($instance, $data); 241 $result[$instance->id] = $instance; 242 } 243 return $result; 244 245 } else { 246 247 return false; 248 } 249 } 250 251 /** 252 * Updates this object in the Database, based on its object variables. ID must be set. 253 * 254 * @return bool success 255 */ 256 public function update() { 257 global $DB; 258 259 if (empty($this->id)) { 260 debugging('Can not update data object, no id!'); 261 return false; 262 } 263 264 $data = $this->get_record_data(); 265 266 $DB->update_record($this->table, $data); 267 268 $this->notify_changed(false); 269 return true; 270 } 271 272 /** 273 * Deletes this object from the database. 274 * 275 * @return bool success 276 */ 277 public function delete() { 278 global $DB; 279 280 if (empty($this->id)) { 281 debugging('Can not delete data object, no id!'); 282 return false; 283 } 284 285 $data = $this->get_record_data(); 286 287 if ($DB->delete_records($this->table, array('id'=>$this->id))) { 288 $this->notify_changed(true); 289 return true; 290 291 } else { 292 return false; 293 } 294 } 295 296 /** 297 * Returns object with fields and values that are defined in database 298 * 299 * @return stdClass 300 */ 301 public function get_record_data() { 302 $data = new stdClass(); 303 304 foreach ($this as $var=>$value) { 305 if (in_array($var, $this->required_fields) or array_key_exists($var, $this->optional_fields)) { 306 if (is_object($value) or is_array($value)) { 307 debugging("Incorrect property '$var' found when inserting data object"); 308 } else { 309 $data->$var = $value; 310 } 311 } 312 } 313 return $data; 314 } 315 316 /** 317 * Records this object in the Database, sets its id to the returned value, and returns that value. 318 * If successful this function also fetches the new object data from database and stores it 319 * in object properties. 320 * 321 * @return int PK ID if successful, false otherwise 322 */ 323 public function insert() { 324 global $DB; 325 326 if (!empty($this->id)) { 327 debugging("Data object already exists!"); 328 return false; 329 } 330 331 $data = $this->get_record_data(); 332 333 $this->id = $DB->insert_record($this->table, $data); 334 335 // set all object properties from real db data 336 $this->update_from_db(); 337 338 $this->notify_changed(false); 339 return $this->id; 340 } 341 342 /** 343 * Using this object's id field, fetches the matching record in the DB, and looks at 344 * each variable in turn. If the DB has different data, the db's data is used to update 345 * the object. This is different from the update() function, which acts on the DB record 346 * based on the object. 347 * 348 * @return bool True for success, false otherwise. 349 */ 350 public function update_from_db() { 351 if (empty($this->id)) { 352 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."); 353 return false; 354 } 355 global $DB; 356 if (!$params = $DB->get_record($this->table, array('id' => $this->id))) { 357 debugging("Object with this id:{$this->id} does not exist in table:{$this->table}, can not update from db!"); 358 return false; 359 } 360 361 self::set_properties($this, $params); 362 363 return true; 364 } 365 366 /** 367 * Given an associated array or object, cycles through each key/variable 368 * and assigns the value to the corresponding variable in this object. 369 * 370 * @final 371 * @param data_object $instance 372 * @param array $params 373 */ 374 public static function set_properties(&$instance, $params) { 375 $params = (array) $params; 376 foreach ($params as $var => $value) { 377 if (in_array($var, $instance->required_fields) or array_key_exists($var, $instance->optional_fields)) { 378 $instance->$var = $value; 379 } 380 } 381 } 382 383 /** 384 * Called immediately after the object data has been inserted, updated, or 385 * deleted in the database. Default does nothing, can be overridden to 386 * hook in special behaviour. 387 * 388 * @param bool $deleted Set this to true if it has been deleted. 389 */ 390 public function notify_changed($deleted) { 391 } 392 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |