Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Content manager class
 *
 * @package    core_contentbank
 * @copyright  2020 Amaia Anabitarte <amaia@moodle.com>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

namespace core_contentbank;

use core_text;
use stored_file;
use stdClass;
use coding_exception;
> use context;
use moodle_url; use core\event\contentbank_content_updated; /** * Content manager class * * @package core_contentbank * @copyright 2020 Amaia Anabitarte <amaia@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ abstract class content { /** @var stdClass $content The content of the current instance. **/ protected $content = null; /** * Content bank constructor * * @param stdClass $record A contentbank_content record. * @throws coding_exception If content type is not right. */ public function __construct(stdClass $record) { // Content type should exist and be linked to plugin classname. $classname = $record->contenttype.'\\content'; if (get_class($this) != $classname) { throw new coding_exception(get_string('contenttypenotfound', 'error', $record->contenttype)); } $typeclass = $record->contenttype.'\\contenttype'; if (!class_exists($typeclass)) { throw new coding_exception(get_string('contenttypenotfound', 'error', $record->contenttype)); } // A record with the id must exist in 'contentbank_content' table. // To improve performance, we are only checking the id is set, but no querying the database. if (!isset($record->id)) { throw new coding_exception(get_string('invalidcontentid', 'error')); } $this->content = $record; } /** * Returns $this->content. * * @return stdClass $this->content. */ public function get_content(): stdClass { return $this->content; } /** * Returns $this->content->contenttype. * * @return string $this->content->contenttype. */ public function get_content_type(): string { return $this->content->contenttype;
> } } > > /** /** > * Return the contenttype instance of this content. * Returns $this->content->timemodified. > * * > * @return contenttype The content type instance * @return int $this->content->timemodified. > */ */ > public function get_content_type_instance(): contenttype { public function get_timemodified(): int { > $context = context::instance_by_id($this->content->contextid); return $this->content->timemodified; > $contenttypeclass = "\\{$this->content->contenttype}\\contenttype"; } > return new $contenttypeclass($context);
/** * Updates content_bank table with information in $this->content. * * @return boolean True if the content has been succesfully updated. False otherwise. * @throws \coding_exception if not loaded. */ public function update_content(): bool { global $USER, $DB; // A record with the id must exist in 'contentbank_content' table. // To improve performance, we are only checking the id is set, but no querying the database. if (!isset($this->content->id)) { throw new coding_exception(get_string('invalidcontentid', 'error')); } $this->content->usermodified = $USER->id; $this->content->timemodified = time(); $result = $DB->update_record('contentbank_content', $this->content); if ($result) { // Trigger an event for updating this content. $event = contentbank_content_updated::create_from_record($this->content); $event->trigger(); } return $result; } /** * Set a new name to the content. * * @param string $name The name of the content. * @return bool True if the content has been succesfully updated. False otherwise. * @throws \coding_exception if not loaded. */ public function set_name(string $name): bool { $name = trim($name); if ($name === '') { return false; } // Clean name. $name = clean_param($name, PARAM_TEXT); if (core_text::strlen($name) > 255) { $name = core_text::substr($name, 0, 255); } $oldname = $this->content->name; $this->content->name = $name; $updated = $this->update_content(); if (!$updated) { $this->content->name = $oldname; } return $updated; } /** * Returns the name of the content. * * @return string The name of the content. */ public function get_name(): string { return $this->content->name; } /** * Set a new contextid to the content. * * @param int $contextid The new contextid of the content. * @return bool True if the content has been succesfully updated. False otherwise. */ public function set_contextid(int $contextid): bool { if ($this->content->contextid == $contextid) { return true; } $oldcontextid = $this->content->contextid; $this->content->contextid = $contextid; $updated = $this->update_content(); if ($updated) { // Move files to new context $fs = get_file_storage(); $fs->move_area_files_to_new_context($oldcontextid, $contextid, 'contentbank', 'public', $this->content->id); } else { $this->content->contextid = $oldcontextid; } return $updated; } /** * Returns the contextid of the content. * * @return int The id of the content context. */ public function get_contextid(): string { return $this->content->contextid; } /** * Returns the content ID. * * @return int The content ID. */ public function get_id(): int { return $this->content->id; } /** * Change the content instanceid value. * * @param int $instanceid New instanceid for this content * @return boolean True if the instanceid has been succesfully updated. False otherwise. */ public function set_instanceid(int $instanceid): bool { $this->content->instanceid = $instanceid; return $this->update_content(); } /** * Returns the $instanceid of this content. * * @return int contentbank instanceid */ public function get_instanceid(): int { return $this->content->instanceid; } /** * Change the content config values. * * @param string $configdata New config information for this content * @return boolean True if the configdata has been succesfully updated. False otherwise. */ public function set_configdata(string $configdata): bool { $this->content->configdata = $configdata; return $this->update_content(); } /** * Return the content config values. * * @return mixed Config information for this content (json decoded) */ public function get_configdata() { return $this->content->configdata; } /** * Import a file as a valid content. * * By default, all content has a public file area to interact with the content bank * repository. This method should be overridden by contentypes which does not simply * upload to the public file area. * * If any, the method will return the final stored_file. This way it can be invoked * as parent::import_file in case any plugin want to store the file in the public area * and also parse it. * * @throws file_exception If file operations fail * @param stored_file $file File to store in the content file area. * @return stored_file|null the stored content file or null if the file is discarted. */ public function import_file(stored_file $file): ?stored_file { $originalfile = $this->get_file(); if ($originalfile) { $originalfile->replace_file_with($file); return $originalfile; } else { $itemid = $this->get_id(); $fs = get_file_storage(); $filerecord = [ 'contextid' => $this->get_contextid(), 'component' => 'contentbank', 'filearea' => 'public', 'itemid' => $this->get_id(), 'filepath' => '/', 'filename' => $file->get_filename(), 'timecreated' => time(), ]; return $fs->create_file_from_storedfile($filerecord, $file); } } /** * Returns the $file related to this content. * * @return stored_file File stored in content bank area related to the given itemid. * @throws \coding_exception if not loaded. */ public function get_file(): ?stored_file { $itemid = $this->get_id(); $fs = get_file_storage(); $files = $fs->get_area_files( $this->content->contextid, 'contentbank', 'public', $itemid, 'itemid, filepath, filename', false ); if (!empty($files)) { $file = reset($files); return $file; } return null; } /** * Returns the file url related to this content. * * @return string URL of the file stored in content bank area related to the given itemid. * @throws \coding_exception if not loaded. */ public function get_file_url(): string { if (!$file = $this->get_file()) { return ''; } $fileurl = moodle_url::make_pluginfile_url( $this->content->contextid, 'contentbank', 'public', $file->get_itemid(), $file->get_filepath(), $file->get_filename() ); return $fileurl; } /** * Returns user has access permission for the content itself (based on what plugin needs). * * @return bool True if content could be accessed. False otherwise. */ public function is_view_allowed(): bool { // There's no capability at content level to check, // but plugins can overwrite this method in case they want to check something related to content properties. return true; } }