2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Content type manager class
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
25 namespace core_contentbank
;
31 * Content type manager class
33 * @package core_contentbank
34 * @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37 abstract class contenttype
{
39 /** Plugin implements uploading feature */
40 const CAN_UPLOAD
= 'upload';
42 /** @var context This content's context. **/
43 protected $context = null;
46 * Content type constructor
48 * @param \context $context Optional context to check (default null)
50 public function __construct(\context
$context = null) {
51 if (empty($context)) {
52 $context = \context_system
::instance();
54 $this->context
= $context;
58 * Fills content_bank table with appropiate information.
60 * @param stdClass $record An optional content record compatible object (default null)
61 * @return content Object with content bank information.
63 public function create_content(\stdClass
$record = null): ?content
{
66 $entry = new \
stdClass();
67 $entry->contenttype
= $this->get_contenttype_name();
68 $entry->contextid
= $this->context
->id
;
69 $entry->name
= $record->name ??
'';
70 $entry->usercreated
= $record->usercreated ??
$USER->id
;
71 $entry->timecreated
= time();
72 $entry->usermodified
= $entry->usercreated
;
73 $entry->timemodified
= $entry->timecreated
;
74 $entry->configdata
= $record->configdata ??
'';
75 $entry->id
= $DB->insert_record('contentbank_content', $entry);
77 $classname = '\\'.$entry->contenttype
.'\\content';
78 return new $classname($entry);
84 * Delete this content from the content_bank.
85 * This method can be overwritten by the plugins if they need to delete specific information.
87 * @param content $content The content to delete.
88 * @return boolean true if the content has been deleted; false otherwise.
90 public function delete_content(content
$content): bool {
93 // Delete the file if it exists.
94 if ($file = $content->get_file()) {
98 // Delete the contentbank DB entry.
99 return $DB->delete_records('contentbank_content', ['id' => $content->get_id()]);
103 * Returns the contenttype name of this content.
105 * @return string Content type of the current instance
107 public function get_contenttype_name(): string {
108 $classname = get_class($this);
109 $contenttype = explode('\\', $classname);
110 return array_shift($contenttype);
114 * Returns the plugin name of the current instance.
116 * @return string Plugin name of the current instance
118 public function get_plugin_name(): string {
119 $contenttype = $this->get_contenttype_name();
120 $plugin = explode('_', $contenttype);
121 return array_pop($plugin);
125 * Returns the URL where the content will be visualized.
127 * @param stdClass $record The content to be displayed.
128 * @return string URL where to visualize the given content.
130 public function get_view_url(\stdClass
$record): string {
131 return new moodle_url('/contentbank/view.php', ['id' => $record->id
]);
135 * Returns the HTML content to add to view.php visualizer.
137 * @param stdClass $record The content to be displayed.
138 * @return string HTML code to include in view.php.
140 public function get_view_content(\stdClass
$record): string {
141 // Main contenttype class can visualize the content, but plugins could overwrite visualization.
146 * Returns the HTML code to render the icon for content bank contents.
148 * @param string $contentname The contentname to add as alt value to the icon.
149 * @return string HTML code to render the icon
151 public function get_icon(string $contentname): string {
153 return $OUTPUT->pix_icon('f/unknown-64', $contentname, 'moodle', ['class' => 'iconsize-big']);
157 * Returns user has access capability for the main content bank and the content itself (base on is_access_allowed from plugin).
159 * @return bool True if content could be accessed. False otherwise.
161 final public function can_access(): bool {
162 $classname = 'contenttype/'.$this->get_plugin_name();
163 $capability = $classname.":access";
164 $hascapabilities = has_capability('moodle/contentbank:access', $this->context
)
165 && has_capability($capability, $this->context
);
166 return $hascapabilities && $this->is_access_allowed();
170 * Returns user has access capability for the content itself.
172 * @return bool True if content could be accessed. False otherwise.
174 protected function is_access_allowed(): bool {
175 // Plugins can overwrite this function to add any check they need.
180 * Returns the user has permission to upload new content.
182 * @return bool True if content could be uploaded. False otherwise.
184 final public function can_upload(): bool {
185 if (!$this->is_feature_supported(self
::CAN_UPLOAD
)) {
188 if (!$this->can_access()) {
192 $classname = 'contenttype/'.$this->get_plugin_name();
193 $uploadcap = $classname.':upload';
194 $hascapabilities = has_capability('moodle/contentbank:upload', $this->context
)
195 && has_capability($uploadcap, $this->context
);
196 return $hascapabilities && $this->is_upload_allowed();
200 * Returns plugin allows uploading.
202 * @return bool True if plugin allows uploading. False otherwise.
204 protected function is_upload_allowed(): bool {
205 // Plugins can overwrite this function to add any check they need.
210 * Check if the user can delete this content.
212 * @param content $content The content to be deleted.
213 * @return bool True if content could be uploaded. False otherwise.
215 final public function can_delete(content
$content): bool {
218 if ($this->context
->id
!= $content->get_content()->contextid
) {
219 // The content has to have exactly the same context as this contenttype.
223 $hascapability = has_capability('moodle/contentbank:deleteanycontent', $this->context
);
224 if ($content->get_content()->usercreated
== $USER->id
) {
225 // This content has been created by the current user; check if she can delete her content.
226 $hascapability = $hascapability ||
has_capability('moodle/contentbank:deleteowncontent', $this->context
);
229 return $hascapability && $this->is_delete_allowed($content);
233 * Returns if content allows deleting.
235 * @param content $content The content to be deleted.
236 * @return bool True if content allows uploading. False otherwise.
238 protected function is_delete_allowed(content
$content): bool {
239 // Plugins can overwrite this function to add any check they need.
244 * Returns the plugin supports the feature.
246 * @param string $feature Feature code e.g CAN_UPLOAD
247 * @return bool True if content could be uploaded. False otherwise.
249 final public function is_feature_supported(string $feature): bool {
250 return in_array($feature, $this->get_implemented_features());
254 * Return an array of implemented features by the plugins.
258 abstract protected function get_implemented_features(): array;
261 * Return an array of extensions the plugins could manage.
265 abstract public function get_manageable_extensions(): array;