MDL-68483 contentbank: improve search API
[moodle.git] / contentbank / classes / content.php
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/>.
17 /**
18  * Content manager class
19  *
20  * @package    core_contentbank
21  * @copyright  2020 Amaia Anabitarte <amaia@moodle.com>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 namespace core_contentbank;
27 use core_text;
28 use stored_file;
29 use stdClass;
30 use coding_exception;
31 use moodle_url;
32 use core\event\contentbank_content_updated;
34 /**
35  * Content manager class
36  *
37  * @package    core_contentbank
38  * @copyright  2020 Amaia Anabitarte <amaia@moodle.com>
39  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40  */
41 abstract class content {
43     /** @var stdClass $content The content of the current instance. **/
44     protected $content  = null;
46     /**
47      * Content bank constructor
48      *
49      * @param stdClass $record A contentbank_content record.
50      * @throws coding_exception If content type is not right.
51      */
52     public function __construct(stdClass $record) {
53         // Content type should exist and be linked to plugin classname.
54         $classname = $record->contenttype.'\\content';
55         if (get_class($this) != $classname) {
56             throw new coding_exception(get_string('contenttypenotfound', 'error', $record->contenttype));
57         }
58         $typeclass = $record->contenttype.'\\contenttype';
59         if (!class_exists($typeclass)) {
60             throw new coding_exception(get_string('contenttypenotfound', 'error', $record->contenttype));
61         }
62         // A record with the id must exist in 'contenbank_content' table.
63         // To improve performance, we are only checking the id is set, but no querying the database.
64         if (!isset($record->id)) {
65             throw new coding_exception(get_string('invalidcontentid', 'error'));
66         }
67         $this->content = $record;
68     }
70     /**
71      * Returns $this->content.
72      *
73      * @return stdClass  $this->content.
74      */
75     public function get_content(): stdClass {
76         return $this->content;
77     }
79     /**
80      * Returns $this->content->contenttype.
81      *
82      * @return string  $this->content->contenttype.
83      */
84     public function get_content_type(): string {
85         return $this->content->contenttype;
86     }
88     /**
89      * Updates content_bank table with information in $this->content.
90      *
91      * @return boolean  True if the content has been succesfully updated. False otherwise.
92      * @throws \coding_exception if not loaded.
93      */
94     public function update_content(): bool {
95         global $USER, $DB;
97         // A record with the id must exist in 'contenbank_content' table.
98         // To improve performance, we are only checking the id is set, but no querying the database.
99         if (!isset($this->content->id)) {
100             throw new coding_exception(get_string('invalidcontentid', 'error'));
101         }
102         $this->content->usermodified = $USER->id;
103         $this->content->timemodified = time();
104         $result = $DB->update_record('contentbank_content', $this->content);
105         if ($result) {
106             // Trigger an event for updating this content.
107             $event = contentbank_content_updated::create_from_record($this->content);
108             $event->trigger();
109         }
110         return $result;
111     }
113     /**
114      * Set a new name to the content.
115      *
116      * @param string $name  The name of the content.
117      * @return bool  True if the content has been succesfully updated. False otherwise.
118      * @throws \coding_exception if not loaded.
119      */
120     public function set_name(string $name): bool {
121         if (empty($name)) {
122             return false;
123         }
125         // Clean name.
126         $name = clean_param($name, PARAM_TEXT);
127         if (core_text::strlen($name) > 255) {
128             $name = core_text::substr($name, 0, 255);
129         }
131         $oldname = $this->content->name;
132         $this->content->name = $name;
133         $updated = $this->update_content();
134         if (!$updated) {
135             $this->content->name = $oldname;
136         }
137         return $updated;
138     }
140     /**
141      * Returns the name of the content.
142      *
143      * @return string   The name of the content.
144      */
145     public function get_name(): string {
146         return $this->content->name;
147     }
149     /**
150      * Returns the content ID.
151      *
152      * @return int   The content ID.
153      */
154     public function get_id(): int {
155         return $this->content->id;
156     }
158     /**
159      * Change the content instanceid value.
160      *
161      * @param int $instanceid    New instanceid for this content
162      * @return boolean           True if the instanceid has been succesfully updated. False otherwise.
163      */
164     public function set_instanceid(int $instanceid): bool {
165         $this->content->instanceid = $instanceid;
166         return $this->update_content();
167     }
169     /**
170      * Returns the $instanceid of this content.
171      *
172      * @return int   contentbank instanceid
173      */
174     public function get_instanceid(): int {
175         return $this->content->instanceid;
176     }
178     /**
179      * Change the content config values.
180      *
181      * @param string $configdata    New config information for this content
182      * @return boolean              True if the configdata has been succesfully updated. False otherwise.
183      */
184     public function set_configdata(string $configdata): bool {
185         $this->content->configdata = $configdata;
186         return $this->update_content();
187     }
189     /**
190      * Return the content config values.
191      *
192      * @return mixed   Config information for this content (json decoded)
193      */
194     public function get_configdata() {
195         return $this->content->configdata;
196     }
198     /**
199      * Returns the $file related to this content.
200      *
201      * @return stored_file  File stored in content bank area related to the given itemid.
202      * @throws \coding_exception if not loaded.
203      */
204     public function get_file(): ?stored_file {
205         $itemid = $this->get_id();
206         $fs = get_file_storage();
207         $files = $fs->get_area_files(
208             $this->content->contextid,
209             'contentbank',
210             'public',
211             $itemid,
212             'itemid, filepath, filename',
213             false
214         );
215         if (!empty($files)) {
216             $file = reset($files);
217             return $file;
218         }
219         return null;
220     }
222     /**
223      * Returns the file url related to this content.
224      *
225      * @return string       URL of the file stored in content bank area related to the given itemid.
226      * @throws \coding_exception if not loaded.
227      */
228     public function get_file_url(): string {
229         if (!$file = $this->get_file()) {
230             return '';
231         }
232         $fileurl = moodle_url::make_pluginfile_url(
233             $this->content->contextid,
234             'contentbank',
235             'public',
236             $file->get_itemid(),
237             $file->get_filepath(),
238             $file->get_filename()
239         );
241         return $fileurl;
242     }
244     /**
245      * Returns user has access permission for the content itself (based on what plugin needs).
246      *
247      * @return bool     True if content could be accessed. False otherwise.
248      */
249     public function is_view_allowed(): bool {
250         // There's no capability at content level to check,
251         // but plugins can overwrite this method in case they want to check something related to content properties.
252         return true;
253     }