Differences Between: [Versions 402 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 namespace core_xapi; 18 19 use core_xapi\local\state; 20 21 /** 22 * The state store manager. 23 * 24 * @package core_xapi 25 * @since Moodle 4.2 26 * @copyright 2022 Ferran Recio <ferran@moodle.com> 27 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 28 */ 29 class state_store { 30 31 /** @var string component name in frankenstyle. */ 32 protected $component; 33 34 /** 35 * Constructor for a xAPI handler base class. 36 * 37 * @param string $component the component name 38 */ 39 public function __construct(string $component) { 40 $this->component = $component; 41 } 42 43 /** 44 * Delete any extra state data stored in the database. 45 * 46 * This method will be called only if the state is accepted by validate_state. 47 * 48 * Plugins may override this method add extra clean up tasks to the deletion. 49 * 50 * @param state $state 51 * @return bool if the state is removed 52 */ 53 public function delete(state $state): bool { 54 global $DB; 55 $data = [ 56 'component' => $this->component, 57 'userid' => $state->get_user()->id, 58 'itemid' => $state->get_activity_id(), 59 'stateid' => $state->get_state_id(), 60 'registration' => $state->get_registration(), 61 ]; 62 return $DB->delete_records('xapi_states', $data); 63 } 64 65 /** 66 * Get a state object from the database. 67 * 68 * This method will be called only if the state is accepted by validate_state. 69 * 70 * Plugins may override this method if they store some data in different tables. 71 * 72 * @param state $state 73 * @return state|null the state 74 */ 75 public function get(state $state): ?state { 76 global $DB; 77 $data = [ 78 'component' => $this->component, 79 'userid' => $state->get_user()->id, 80 'itemid' => $state->get_activity_id(), 81 'stateid' => $state->get_state_id(), 82 'registration' => $state->get_registration(), 83 ]; 84 $record = $DB->get_record('xapi_states', $data); 85 if ($record) { 86 $statedata = null; 87 if ($record->statedata !== null) { 88 $statedata = json_decode($record->statedata, null, 512, JSON_THROW_ON_ERROR); 89 } 90 $state->set_state_data($statedata); 91 return $state; 92 } 93 94 return null; 95 } 96 97 /** 98 * Inserts an state object into the database. 99 * 100 * This method will be called only if the state is accepted by validate_state. 101 * 102 * Plugins may override this method if they store some data in different tables. 103 * 104 * @param state $state 105 * @return bool if the state is inserted/updated 106 */ 107 public function put(state $state): bool { 108 global $DB; 109 $data = [ 110 'component' => $this->component, 111 'userid' => $state->get_user()->id, 112 'itemid' => $state->get_activity_id(), 113 'stateid' => $state->get_state_id(), 114 'registration' => $state->get_registration(), 115 ]; 116 $record = $DB->get_record('xapi_states', $data) ?: (object) $data; 117 if (isset($record->id)) { 118 $record->statedata = json_encode($state->jsonSerialize()); 119 $record->timemodified = time(); 120 $result = $DB->update_record('xapi_states', $record); 121 } else { 122 $data['statedata'] = json_encode($state->jsonSerialize()); 123 $data['timecreated'] = time(); 124 $data['timemodified'] = $data['timecreated']; 125 $result = $DB->insert_record('xapi_states', $data); 126 } 127 return $result ? true : false; 128 } 129 130 /** 131 * Reset all states from the component. 132 * The given parameters are filters to decide the states to reset. If no parameters are defined, the only filter applied 133 * will be the component. 134 * 135 * Plugins may override this method if they store some data in different tables. 136 * 137 * @param string|null $itemid 138 * @param int|null $userid 139 * @param string|null $stateid 140 * @param string|null $registration 141 */ 142 public function reset( 143 ?string $itemid = null, 144 ?int $userid = null, 145 ?string $stateid = null, 146 ?string $registration = null 147 ): void { 148 global $DB; 149 150 $data = [ 151 'component' => $this->component, 152 ]; 153 if ($itemid) { 154 $data['itemid'] = $itemid; 155 } 156 if ($userid) { 157 $data['userid'] = $userid; 158 } 159 if ($stateid) { 160 $data['stateid'] = $stateid; 161 } 162 if ($registration) { 163 $data['registration'] = $registration; 164 } 165 $DB->set_field('xapi_states', 'statedata', null, $data); 166 } 167 168 /** 169 * Remove all states from the component 170 * The given parameters are filters to decide the states to wipe. If no parameters are defined, the only filter applied 171 * will be the component. 172 * 173 * Plugins may override this method if they store some data in different tables. 174 * 175 * @param string|null $itemid 176 * @param int|null $userid 177 * @param string|null $stateid 178 * @param string|null $registration 179 */ 180 public function wipe( 181 ?string $itemid = null, 182 ?int $userid = null, 183 ?string $stateid = null, 184 ?string $registration = null 185 ): void { 186 global $DB; 187 $data = [ 188 'component' => $this->component, 189 ]; 190 if ($itemid) { 191 $data['itemid'] = $itemid; 192 } 193 if ($userid) { 194 $data['userid'] = $userid; 195 } 196 if ($stateid) { 197 $data['stateid'] = $stateid; 198 } 199 if ($registration) { 200 $data['registration'] = $registration; 201 } 202 $DB->delete_records('xapi_states', $data); 203 } 204 205 /** 206 * Get all state ids from a specific activity and agent. 207 * 208 * Plugins may override this method if they store some data in different tables. 209 * 210 * @param string|null $itemid 211 * @param int|null $userid 212 * @param string|null $registration 213 * @param int|null $since filter ids updated since a specific timestamp 214 * @return string[] the state ids values 215 */ 216 public function get_state_ids( 217 ?string $itemid = null, 218 ?int $userid = null, 219 ?string $registration = null, 220 ?int $since = null, 221 ): array { 222 global $DB; 223 $select = 'component = :component'; 224 $params = [ 225 'component' => $this->component, 226 ]; 227 if ($itemid) { 228 $select .= ' AND itemid = :itemid'; 229 $params['itemid'] = $itemid; 230 } 231 if ($userid) { 232 $select .= ' AND userid = :userid'; 233 $params['userid'] = $userid; 234 } 235 if ($registration) { 236 $select .= ' AND registration = :registration'; 237 $params['registration'] = $registration; 238 } 239 if ($since) { 240 $select .= ' AND timemodified > :since'; 241 $params['since'] = $since; 242 } 243 return $DB->get_fieldset_select('xapi_states', 'stateid', $select, $params, ''); 244 } 245 246 /** 247 * Execute a state store clean up. 248 * 249 * Plugins can override this methos to provide an alternative clean up logic. 250 */ 251 public function cleanup(): void { 252 global $DB; 253 $xapicleanupperiod = get_config('core', 'xapicleanupperiod'); 254 if (empty($xapicleanupperiod)) { 255 return; 256 } 257 $todelete = time() - $xapicleanupperiod; 258 $DB->delete_records_select( 259 'xapi_states', 260 'component = :component AND timemodified < :todelete', 261 ['component' => $this->component, 'todelete' => $todelete] 262 ); 263 } 264 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body