MDL-68483 contentbank: improve search API
[moodle.git] / contentbank / classes / content.php
CommitLineData
33b8ca26
AA
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 * 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 */
24
25namespace core_contentbank;
26
448012c6 27use core_text;
33b8ca26
AA
28use stored_file;
29use stdClass;
30use coding_exception;
31use moodle_url;
db15dab8 32use core\event\contentbank_content_updated;
33b8ca26
AA
33
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 */
41abstract class content {
42
43 /** @var stdClass $content The content of the current instance. **/
44 protected $content = null;
45
46 /**
47 * Content bank constructor
48 *
de322e3d 49 * @param stdClass $record A contentbank_content record.
33b8ca26
AA
50 * @throws coding_exception If content type is not right.
51 */
de322e3d 52 public function __construct(stdClass $record) {
33b8ca26 53 // Content type should exist and be linked to plugin classname.
de322e3d 54 $classname = $record->contenttype.'\\content';
33b8ca26 55 if (get_class($this) != $classname) {
de322e3d 56 throw new coding_exception(get_string('contenttypenotfound', 'error', $record->contenttype));
33b8ca26 57 }
de322e3d 58 $typeclass = $record->contenttype.'\\contenttype';
33b8ca26 59 if (!class_exists($typeclass)) {
de322e3d 60 throw new coding_exception(get_string('contenttypenotfound', 'error', $record->contenttype));
33b8ca26
AA
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.
de322e3d 64 if (!isset($record->id)) {
33b8ca26
AA
65 throw new coding_exception(get_string('invalidcontentid', 'error'));
66 }
de322e3d 67 $this->content = $record;
33b8ca26
AA
68 }
69
70 /**
71 * Returns $this->content.
72 *
73 * @return stdClass $this->content.
74 */
75 public function get_content(): stdClass {
76 return $this->content;
77 }
78
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 }
87
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;
96
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();
fb302d38
AA
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;
33b8ca26
AA
111 }
112
448012c6
AA
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 }
124
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 }
130
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 }
139
33b8ca26
AA
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 }
148
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 }
157
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 }
168
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 }
177
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 }
188
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 }
197
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 }
221
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 );
240
241 return $fileurl;
242 }
243
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 */
fb445c76 249 public function is_view_allowed(): bool {
33b8ca26
AA
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 }
254}