Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
            'uniquekey' => false
100
        ];
101
 
102
        $requiredfields = array_filter($allowedfields, function($field) {
103
            return $field;
104
        });
105
 
106
        if ($missingfields = array_keys(array_diff_key($requiredfields, $favourite))) {
107
            throw new \moodle_exception("Missing object property(s) '" . join(', ', $missingfields) . "'.");
108
        }
109
 
110
        // If the record contains fields we don't allow, throw an exception.
111
        if ($unsupportedfields = array_keys(array_diff_key($favourite, $allowedfields))) {
112
            throw new \moodle_exception("Unexpected object property(s) '" . join(', ', $unsupportedfields) . "'.");
113
        }
114
    }
115
 
116
    /**
117
     * Add a favourite to the repository.
118
     *
119
     * @param favourite $favourite the favourite to add.
120
     * @return favourite the favourite which has been stored.
121
     * @throws \dml_exception if any database errors are encountered.
122
     * @throws \moodle_exception if the favourite has missing or invalid properties.
123
     */
124
    public function add(favourite $favourite): favourite {
125
        global $DB;
126
        $this->validate($favourite);
127
        $favourite = (array)$favourite;
128
        $time = time();
129
        $favourite['timecreated'] = $time;
130
        $favourite['timemodified'] = $time;
131
        $id = $DB->insert_record($this->favouritetable, $favourite);
132
        return $this->find($id);
133
    }
134
 
135
    /**
136
     * Add a collection of favourites to the repository.
137
     *
138
     * @param array $items the list of favourites to add.
139
     * @return array the list of favourites which have been stored.
140
     * @throws \dml_exception if any database errors are encountered.
141
     * @throws \moodle_exception if any of the favourites have missing or invalid properties.
142
     */
143
    public function add_all(array $items): array {
144
        global $DB;
145
        $time = time();
146
        foreach ($items as $item) {
147
            $this->validate($item);
148
            $favourite = (array)$item;
149
            $favourite['timecreated'] = $time;
150
            $favourite['timemodified'] = $time;
151
            $ids[] = $DB->insert_record($this->favouritetable, $favourite);
152
        }
153
        list($insql, $params) = $DB->get_in_or_equal($ids);
154
        $records = $DB->get_records_select($this->favouritetable, "id $insql", $params);
155
        return $this->get_list_of_favourites_from_records($records);
156
    }
157
 
158
    /**
159
     * Find a favourite by id.
160
     *
161
     * @param int $id the id of the favourite.
162
     * @return favourite the favourite.
163
     * @throws \dml_exception if any database errors are encountered.
164
     */
165
    public function find(int $id): favourite {
166
        global $DB;
167
        $record = $DB->get_record($this->favouritetable, ['id' => $id], '*', MUST_EXIST);
168
        return $this->get_favourite_from_record($record);
169
    }
170
 
171
    /**
172
     * Return all items in this repository, as an array, indexed by id.
173
     *
174
     * @param int $limitfrom optional pagination control for returning a subset of records, starting at this point.
175
     * @param int $limitnum optional pagination control for returning a subset comprising this many records.
176
     * @return array the list of all favourites stored within this repository.
177
     * @throws \dml_exception if any database errors are encountered.
178
     */
179
    public function find_all(int $limitfrom = 0, int $limitnum = 0): array {
180
        global $DB;
181
        $records = $DB->get_records($this->favouritetable, null, '', '*', $limitfrom, $limitnum);
182
        return $this->get_list_of_favourites_from_records($records);
183
    }
184
 
185
    /**
186
     * Return all items matching the supplied criteria (a [key => value,..] list).
187
     *
188
     * @param array $criteria the list of key/value(s) criteria pairs.
189
     * @param int $limitfrom optional pagination control for returning a subset of records, starting at this point.
190
     * @param int $limitnum optional pagination control for returning a subset comprising this many records.
191
     * @return array the list of favourites matching the criteria.
192
     * @throws \dml_exception if any database errors are encountered.
193
     */
194
    public function find_by(array $criteria, int $limitfrom = 0, int $limitnum = 0): array {
195
        global $DB;
196
        $conditions = [];
197
        $params = [];
198
        foreach ($criteria as $field => $value) {
199
            if (is_array($value) && count($value)) {
200
                list($insql, $inparams) = $DB->get_in_or_equal($value, SQL_PARAMS_NAMED);
201
                $conditions[] = "$field $insql";
202
                $params = array_merge($params, $inparams);
203
            } else {
204
                $conditions[] = "$field = :$field";
205
                $params = array_merge($params, [$field => $value]);
206
            }
207
        }
208
 
209
        $records = $DB->get_records_select($this->favouritetable, implode(' AND ', $conditions), $params,
210
            '', '*', $limitfrom, $limitnum);
211
 
212
        return $this->get_list_of_favourites_from_records($records);
213
    }
214
 
215
    /**
216
     * Find a specific favourite, based on the properties known to identify it.
217
     *
218
     * Used if we don't know its id.
219
     *
220
     * @param int $userid the id of the user to which the favourite belongs.
221
     * @param string $component the frankenstyle component name.
222
     * @param string $itemtype the type of the favourited item.
223
     * @param int $itemid the id of the item which was favourited (not the favourite's id).
224
     * @param int $contextid the contextid of the item which was favourited.
225
     * @return favourite the favourite.
226
     * @throws \dml_exception if any database errors are encountered or if the record could not be found.
227
     */
228
    public function find_favourite(int $userid, string $component, string $itemtype, int $itemid, int $contextid): favourite {
229
        global $DB;
230
        // Favourites model: We know that only one favourite can exist based on these properties.
231
        $record = $DB->get_record($this->favouritetable, [
232
            'userid' => $userid,
233
            'component' => $component,
234
            'itemtype' => $itemtype,
235
            'itemid' => $itemid,
236
            'contextid' => $contextid
237
        ], '*', MUST_EXIST);
238
        return $this->get_favourite_from_record($record);
239
    }
240
 
241
    /**
242
     * Check whether a favourite exists in this repository, based on its id.
243
     *
244
     * @param int $id the id to search for.
245
     * @return bool true if the favourite exists, false otherwise.
246
     * @throws \dml_exception if any database errors are encountered.
247
     */
248
    public function exists(int $id): bool {
249
        global $DB;
250
        return $DB->record_exists($this->favouritetable, ['id' => $id]);
251
    }
252
 
253
    /**
254
     * Check whether an item exists in this repository, based on the specified criteria.
255
     *
256
     * @param array $criteria the list of key/value criteria pairs.
257
     * @return bool true if the favourite exists, false otherwise.
258
     * @throws \dml_exception if any database errors are encountered.
259
     */
260
    public function exists_by(array $criteria): bool {
261
        global $DB;
262
        return $DB->record_exists($this->favouritetable, $criteria);
263
    }
264
 
265
    /**
266
     * Update a favourite.
267
     *
268
     * @param favourite $favourite the favourite to update.
269
     * @return favourite the updated favourite.
270
     * @throws \dml_exception if any database errors are encountered.
271
     */
272
    public function update(favourite $favourite): favourite {
273
        global $DB;
274
        $time = time();
275
        $favourite->timemodified = $time;
276
        $DB->update_record($this->favouritetable, $favourite);
277
        return $this->find($favourite->id);
278
    }
279
 
280
    /**
281
     * Delete a favourite, by id.
282
     *
283
     * @param int $id the id of the favourite to delete.
284
     * @throws \dml_exception if any database errors are encountered.
285
     */
286
    public function delete(int $id) {
287
        global $DB;
288
        $DB->delete_records($this->favouritetable, ['id' => $id]);
289
    }
290
 
291
    /**
292
     * Delete all favourites matching the specified criteria.
293
     *
294
     * @param array $criteria the list of key/value criteria pairs.
295
     * @throws \dml_exception if any database errors are encountered.
296
     */
297
    public function delete_by(array $criteria) {
298
        global $DB;
299
        $DB->delete_records($this->favouritetable, $criteria);
300
    }
301
 
302
    /**
303
     * Return the total number of favourites in this repository.
304
     *
305
     * @return int the total number of items.
306
     * @throws \dml_exception if any database errors are encountered.
307
     */
308
    public function count(): int {
309
        global $DB;
310
        return $DB->count_records($this->favouritetable);
311
    }
312
 
313
    /**
314
     * Return the number of user favourites matching the specified criteria.
315
     *
316
     * @param array $criteria the list of key/value criteria pairs.
317
     * @return int the number of favourites matching the criteria.
318
     * @throws \dml_exception if any database errors are encountered.
319
     */
320
    public function count_by(array $criteria): int {
321
        global $DB;
322
        return $DB->count_records($this->favouritetable, $criteria);
323
    }
324
}