Differences Between: [Versions 311 and 402] [Versions 311 and 403]
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 * Contains the favourite_repository class, responsible for CRUD operations for favourites. 18 * 19 * @package core_favourites 20 * @copyright 2018 Jake Dallimore <jrhdallimore@gmail.com> 21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 22 */ 23 namespace core_favourites\local\repository; 24 use \core_favourites\local\entity\favourite; 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 /** 29 * Class favourite_repository. 30 * 31 * This class handles persistence of favourites. Favourites from all areas are supported by this repository. 32 * 33 * @copyright 2018 Jake Dallimore <jrhdallimore@gmail.com> 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 */ 36 class favourite_repository implements favourite_repository_interface { 37 38 /** 39 * @var string the name of the table which favourites are stored in. 40 */ 41 protected $favouritetable = 'favourite'; 42 43 /** 44 * Get a favourite object, based on a full record. 45 * @param \stdClass $record the record we wish to hydrate. 46 * @return favourite the favourite record. 47 */ 48 protected function get_favourite_from_record(\stdClass $record) : favourite { 49 $favourite = new favourite( 50 $record->component, 51 $record->itemtype, 52 $record->itemid, 53 $record->contextid, 54 $record->userid 55 ); 56 $favourite->id = $record->id; 57 $favourite->ordering = $record->ordering ?? null; 58 $favourite->timecreated = $record->timecreated ?? null; 59 $favourite->timemodified = $record->timemodified ?? null; 60 61 return $favourite; 62 } 63 64 /** 65 * Get a list of favourite objects, based on a list of records. 66 * @param array $records the record we wish to hydrate. 67 * @return array the list of favourites. 68 */ 69 protected function get_list_of_favourites_from_records(array $records) { 70 $list = []; 71 foreach ($records as $index => $record) { 72 $list[$index] = $this->get_favourite_from_record($record); 73 } 74 return $list; 75 } 76 77 /** 78 * Basic validation, confirming we have the minimum field set needed to save a record to the store. 79 * 80 * @param favourite $favourite the favourite record to validate. 81 * @throws \moodle_exception if the supplied favourite has missing or unsupported fields. 82 */ 83 protected function validate(favourite $favourite) { 84 85 $favourite = (array)$favourite; 86 87 // The allowed fields, and whether or not each is required to create a record. 88 // The timecreated, timemodified and id fields are generated during create/update. 89 $allowedfields = [ 90 'userid' => true, 91 'component' => true, 92 'itemtype' => true, 93 'itemid' => true, 94 'contextid' => true, 95 'ordering' => false, 96 'timecreated' => false, 97 'timemodified' => false, 98 'id' => false 99 ]; 100 101 $requiredfields = array_filter($allowedfields, function($field) { 102 return $field; 103 }); 104 105 if ($missingfields = array_keys(array_diff_key($requiredfields, $favourite))) { 106 throw new \moodle_exception("Missing object property(s) '" . join(', ', $missingfields) . "'."); 107 } 108 109 // If the record contains fields we don't allow, throw an exception. 110 if ($unsupportedfields = array_keys(array_diff_key($favourite, $allowedfields))) { 111 throw new \moodle_exception("Unexpected object property(s) '" . join(', ', $unsupportedfields) . "'."); 112 } 113 } 114 115 /** 116 * Add a favourite to the repository. 117 * 118 * @param favourite $favourite the favourite to add. 119 * @return favourite the favourite which has been stored. 120 * @throws \dml_exception if any database errors are encountered. 121 * @throws \moodle_exception if the favourite has missing or invalid properties. 122 */ 123 public function add(favourite $favourite) : favourite { 124 global $DB; 125 $this->validate($favourite); 126 $favourite = (array)$favourite; 127 $time = time(); 128 $favourite['timecreated'] = $time; 129 $favourite['timemodified'] = $time; 130 $id = $DB->insert_record($this->favouritetable, $favourite); 131 return $this->find($id); 132 } 133 134 /** 135 * Add a collection of favourites to the repository. 136 * 137 * @param array $items the list of favourites to add. 138 * @return array the list of favourites which have been stored. 139 * @throws \dml_exception if any database errors are encountered. 140 * @throws \moodle_exception if any of the favourites have missing or invalid properties. 141 */ 142 public function add_all(array $items) : array { 143 global $DB; 144 $time = time(); 145 foreach ($items as $item) { 146 $this->validate($item); 147 $favourite = (array)$item; 148 $favourite['timecreated'] = $time; 149 $favourite['timemodified'] = $time; 150 $ids[] = $DB->insert_record($this->favouritetable, $favourite); 151 } 152 list($insql, $params) = $DB->get_in_or_equal($ids); 153 $records = $DB->get_records_select($this->favouritetable, "id $insql", $params); 154 return $this->get_list_of_favourites_from_records($records); 155 } 156 157 /** 158 * Find a favourite by id. 159 * 160 * @param int $id the id of the favourite. 161 * @return favourite the favourite. 162 * @throws \dml_exception if any database errors are encountered. 163 */ 164 public function find(int $id) : favourite { 165 global $DB; 166 $record = $DB->get_record($this->favouritetable, ['id' => $id], '*', MUST_EXIST); 167 return $this->get_favourite_from_record($record); 168 } 169 170 /** 171 * Return all items in this repository, as an array, indexed by id. 172 * 173 * @param int $limitfrom optional pagination control for returning a subset of records, starting at this point. 174 * @param int $limitnum optional pagination control for returning a subset comprising this many records. 175 * @return array the list of all favourites stored within this repository. 176 * @throws \dml_exception if any database errors are encountered. 177 */ 178 public function find_all(int $limitfrom = 0, int $limitnum = 0) : array { 179 global $DB; 180 $records = $DB->get_records($this->favouritetable, null, '', '*', $limitfrom, $limitnum); 181 return $this->get_list_of_favourites_from_records($records); 182 } 183 184 /** 185 * Return all items matching the supplied criteria (a [key => value,..] list). 186 * 187 * @param array $criteria the list of key/value(s) criteria pairs. 188 * @param int $limitfrom optional pagination control for returning a subset of records, starting at this point. 189 * @param int $limitnum optional pagination control for returning a subset comprising this many records. 190 * @return array the list of favourites matching the criteria. 191 * @throws \dml_exception if any database errors are encountered. 192 */ 193 public function find_by(array $criteria, int $limitfrom = 0, int $limitnum = 0) : array { 194 global $DB; 195 $conditions = []; 196 $params = []; 197 foreach ($criteria as $field => $value) { 198 if (is_array($value) && count($value)) { 199 list($insql, $inparams) = $DB->get_in_or_equal($value, SQL_PARAMS_NAMED); 200 $conditions[] = "$field $insql"; 201 $params = array_merge($params, $inparams); 202 } else { 203 $conditions[] = "$field = :$field"; 204 $params = array_merge($params, [$field => $value]); 205 } 206 } 207 208 $records = $DB->get_records_select($this->favouritetable, implode(' AND ', $conditions), $params, 209 '', '*', $limitfrom, $limitnum); 210 211 return $this->get_list_of_favourites_from_records($records); 212 } 213 214 /** 215 * Find a specific favourite, based on the properties known to identify it. 216 * 217 * Used if we don't know its id. 218 * 219 * @param int $userid the id of the user to which the favourite belongs. 220 * @param string $component the frankenstyle component name. 221 * @param string $itemtype the type of the favourited item. 222 * @param int $itemid the id of the item which was favourited (not the favourite's id). 223 * @param int $contextid the contextid of the item which was favourited. 224 * @return favourite the favourite. 225 * @throws \dml_exception if any database errors are encountered or if the record could not be found. 226 */ 227 public function find_favourite(int $userid, string $component, string $itemtype, int $itemid, int $contextid) : favourite { 228 global $DB; 229 // Favourites model: We know that only one favourite can exist based on these properties. 230 $record = $DB->get_record($this->favouritetable, [ 231 'userid' => $userid, 232 'component' => $component, 233 'itemtype' => $itemtype, 234 'itemid' => $itemid, 235 'contextid' => $contextid 236 ], '*', MUST_EXIST); 237 return $this->get_favourite_from_record($record); 238 } 239 240 /** 241 * Check whether a favourite exists in this repository, based on its id. 242 * 243 * @param int $id the id to search for. 244 * @return bool true if the favourite exists, false otherwise. 245 * @throws \dml_exception if any database errors are encountered. 246 */ 247 public function exists(int $id) : bool { 248 global $DB; 249 return $DB->record_exists($this->favouritetable, ['id' => $id]); 250 } 251 252 /** 253 * Check whether an item exists in this repository, based on the specified criteria. 254 * 255 * @param array $criteria the list of key/value criteria pairs. 256 * @return bool true if the favourite exists, false otherwise. 257 * @throws \dml_exception if any database errors are encountered. 258 */ 259 public function exists_by(array $criteria) : bool { 260 global $DB; 261 return $DB->record_exists($this->favouritetable, $criteria); 262 } 263 264 /** 265 * Update a favourite. 266 * 267 * @param favourite $favourite the favourite to update. 268 * @return favourite the updated favourite. 269 * @throws \dml_exception if any database errors are encountered. 270 */ 271 public function update(favourite $favourite) : favourite { 272 global $DB; 273 $time = time(); 274 $favourite->timemodified = $time; 275 $DB->update_record($this->favouritetable, $favourite); 276 return $this->find($favourite->id); 277 } 278 279 /** 280 * Delete a favourite, by id. 281 * 282 * @param int $id the id of the favourite to delete. 283 * @throws \dml_exception if any database errors are encountered. 284 */ 285 public function delete(int $id) { 286 global $DB; 287 $DB->delete_records($this->favouritetable, ['id' => $id]); 288 } 289 290 /** 291 * Delete all favourites matching the specified criteria. 292 * 293 * @param array $criteria the list of key/value criteria pairs. 294 * @throws \dml_exception if any database errors are encountered. 295 */ 296 public function delete_by(array $criteria) { 297 global $DB; 298 $DB->delete_records($this->favouritetable, $criteria); 299 } 300 301 /** 302 * Return the total number of favourites in this repository. 303 * 304 * @return int the total number of items. 305 * @throws \dml_exception if any database errors are encountered. 306 */ 307 public function count() : int { 308 global $DB; 309 return $DB->count_records($this->favouritetable); 310 } 311 312 /** 313 * Return the number of user favourites matching the specified criteria. 314 * 315 * @param array $criteria the list of key/value criteria pairs. 316 * @return int the number of favourites matching the criteria. 317 * @throws \dml_exception if any database errors are encountered. 318 */ 319 public function count_by(array $criteria) : int { 320 global $DB; 321 return $DB->count_records($this->favouritetable, $criteria); 322 } 323 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body