mirror of
https://github.com/moodle/moodle.git
synced 2025-04-14 04:52:36 +02:00
Merge branch 'MDL-67786-master' of git://github.com/aanabit/moodle
This commit is contained in:
commit
8467cbf226
84
admin/contentbank.php
Normal file
84
admin/contentbank.php
Normal file
@ -0,0 +1,84 @@
|
||||
<?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 bank and its plugins settings.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage contentbank
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
$action = required_param('action', PARAM_ALPHANUMEXT);
|
||||
$name = required_param('name', PARAM_PLUGIN);
|
||||
|
||||
$syscontext = context_system::instance();
|
||||
$PAGE->set_url('/admin/contentbank.php');
|
||||
$PAGE->set_context($syscontext);
|
||||
|
||||
require_admin();
|
||||
require_sesskey();
|
||||
|
||||
$return = new moodle_url('/admin/settings.php', array('section' => 'managecontentbanktypes'));
|
||||
|
||||
$plugins = core_plugin_manager::instance()->get_plugins_of_type('contenttype');
|
||||
$sortorder = array_flip(array_keys($plugins));
|
||||
|
||||
if (!isset($plugins[$name])) {
|
||||
print_error('contenttypenotfound', 'error', $return, $name);
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'disable':
|
||||
if ($plugins[$name]->is_enabled()) {
|
||||
set_config('disabled', 1, 'contentbank_'. $name);
|
||||
}
|
||||
break;
|
||||
case 'enable':
|
||||
if (!$plugins[$name]->is_enabled()) {
|
||||
unset_config('disabled', 'contentbank_'. $name);
|
||||
}
|
||||
break;
|
||||
case 'up':
|
||||
if ($sortorder[$name]) {
|
||||
$currentindex = $sortorder[$name];
|
||||
$seq = array_keys($plugins);
|
||||
$seq[$currentindex] = $seq[$currentindex - 1];
|
||||
$seq[$currentindex - 1] = $name;
|
||||
set_config('contentbank_plugins_sortorder', implode(',', $seq));
|
||||
}
|
||||
break;
|
||||
case 'down':
|
||||
if ($sortorder[$name] < count($sortorder) - 1) {
|
||||
$currentindex = $sortorder[$name];
|
||||
$seq = array_keys($plugins);
|
||||
$seq[$currentindex] = $seq[$currentindex + 1];
|
||||
$seq[$currentindex + 1] = $name;
|
||||
set_config('contentbank_plugins_sortorder', implode(',', $seq));
|
||||
}
|
||||
break;
|
||||
}
|
||||
core_plugin_manager::reset_caches();
|
||||
$cache = cache::make('core', 'contentbank_enabled_extensions');
|
||||
$cache->purge();
|
||||
$cache = cache::make('core', 'contentbank_context_extensions');
|
||||
$cache->purge();
|
||||
|
||||
redirect($return);
|
@ -657,6 +657,19 @@ if ($hassiteconfig) {
|
||||
}
|
||||
}
|
||||
|
||||
// Content bank content types.
|
||||
if ($hassiteconfig) {
|
||||
$ADMIN->add('modules', new admin_category('contenbanksettings', new lang_string('contentbank')));
|
||||
$temp = new admin_settingpage('managecontentbanktypes', new lang_string('managecontentbanktypes'));
|
||||
$temp->add(new admin_setting_managecontentbankcontenttypes());
|
||||
$ADMIN->add('contenbanksettings', $temp);
|
||||
$plugins = core_plugin_manager::instance()->get_plugins_of_type('contenttype');
|
||||
foreach ($plugins as $plugin) {
|
||||
/** @var \core\plugininfo\contentbank $plugin */
|
||||
$plugin->load_settings($ADMIN, 'contenbanksettings', $hassiteconfig);
|
||||
}
|
||||
}
|
||||
|
||||
/// Add all local plugins - must be always last!
|
||||
if ($hassiteconfig) {
|
||||
$ADMIN->add('modules', new admin_category('localplugins', new lang_string('localplugins')));
|
||||
|
219
contentbank/classes/content.php
Normal file
219
contentbank/classes/content.php
Normal file
@ -0,0 +1,219 @@
|
||||
<?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 stored_file;
|
||||
use stdClass;
|
||||
use coding_exception;
|
||||
use moodle_url;
|
||||
|
||||
/**
|
||||
* 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 $content A contentbanck_content record.
|
||||
* @throws coding_exception If content type is not right.
|
||||
*/
|
||||
public function __construct(stdClass $content) {
|
||||
// Content type should exist and be linked to plugin classname.
|
||||
$classname = $content->contenttype.'\\content';
|
||||
if (get_class($this) != $classname) {
|
||||
throw new coding_exception(get_string('contenttypenotfound', 'error', $content->contenttype));
|
||||
}
|
||||
$typeclass = $content->contenttype.'\\contenttype';
|
||||
if (!class_exists($typeclass)) {
|
||||
throw new coding_exception(get_string('contenttypenotfound', 'error', $content->contenttype));
|
||||
}
|
||||
// A record with the id must exist in 'contenbank_content' table.
|
||||
// To improve performance, we are only checking the id is set, but no querying the database.
|
||||
if (!isset($content->id)) {
|
||||
throw new coding_exception(get_string('invalidcontentid', 'error'));
|
||||
}
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 'contenbank_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();
|
||||
return $DB->update_record('contentbank_content', $this->content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the content.
|
||||
*
|
||||
* @return string The name of the content.
|
||||
*/
|
||||
public function get_name(): string {
|
||||
return $this->content->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 can_view(): 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;
|
||||
}
|
||||
}
|
158
contentbank/classes/contentbank.php
Normal file
158
contentbank/classes/contentbank.php
Normal file
@ -0,0 +1,158 @@
|
||||
<?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 bank 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;
|
||||
|
||||
/**
|
||||
* Content bank 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
|
||||
*/
|
||||
class contentbank {
|
||||
|
||||
/**
|
||||
* Obtains the list of core_contentbank_content objects currently active.
|
||||
*
|
||||
* The list does not include players which are disabled.
|
||||
*
|
||||
* @return string[] Array of contentbank contenttypes.
|
||||
*/
|
||||
private function get_enabled_content_types(): array {
|
||||
$enabledtypes = \core\plugininfo\contenttype::get_enabled_plugins();
|
||||
$types = [];
|
||||
foreach ($enabledtypes as $name) {
|
||||
$classname = "\\contenttype_$name\\contenttype";
|
||||
if (class_exists($classname)) {
|
||||
$types[] = $name;
|
||||
}
|
||||
}
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains an array of supported extensions by active plugins.
|
||||
*
|
||||
* @return array The array with all the extensions supported and the supporting plugin names.
|
||||
*/
|
||||
public function load_all_supported_extensions(): array {
|
||||
$extensionscache = \cache::make('core', 'contentbank_enabled_extensions');
|
||||
$supportedextensions = $extensionscache->get('enabled_extensions');
|
||||
if ($supportedextensions === false) {
|
||||
// Load all enabled extensions.
|
||||
$supportedextensions = [];
|
||||
foreach ($this->get_enabled_content_types() as $type) {
|
||||
$classname = "\\contenttype_$type\\contenttype";
|
||||
if (class_exists($classname)) {
|
||||
$manager = new $classname;
|
||||
if ($manager->is_feature_supported($manager::CAN_UPLOAD)) {
|
||||
$extensions = $manager->get_manageable_extensions();
|
||||
foreach ($extensions as $extension) {
|
||||
if (array_key_exists($extension, $supportedextensions)) {
|
||||
$supportedextensions[$extension][] = $type;
|
||||
} else {
|
||||
$supportedextensions[$extension] = [$type];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$extensionscache->set('enabled_extensions', $supportedextensions);
|
||||
}
|
||||
return $supportedextensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains an array of supported extensions in the given context.
|
||||
*
|
||||
* @param \context $context Optional context to check (default null)
|
||||
* @return array The array with all the extensions supported and the supporting plugin names.
|
||||
*/
|
||||
public function load_context_supported_extensions(\context $context = null): array {
|
||||
$extensionscache = \cache::make('core', 'contentbank_context_extensions');
|
||||
|
||||
$contextextensions = $extensionscache->get($context->id);
|
||||
if ($contextextensions === false) {
|
||||
$contextextensions = [];
|
||||
$supportedextensions = $this->load_all_supported_extensions();
|
||||
foreach ($supportedextensions as $extension => $types) {
|
||||
foreach ($types as $type) {
|
||||
$classname = "\\contenttype_$type\\contenttype";
|
||||
if (class_exists($classname)) {
|
||||
$manager = new $classname($context);
|
||||
if ($manager->can_upload()) {
|
||||
$contextextensions[$extension] = $type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$extensionscache->set($context->id, $contextextensions);
|
||||
}
|
||||
return $contextextensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a string with all supported extensions by active plugins.
|
||||
* Mainly to use as filepicker options parameter.
|
||||
*
|
||||
* @param \context $context Optional context to check (default null)
|
||||
* @return string A string with all the extensions supported.
|
||||
*/
|
||||
public function get_supported_extensions_as_string(\context $context = null) {
|
||||
$supported = $this->load_context_supported_extensions($context);
|
||||
$extensions = array_keys($supported);
|
||||
return implode(',', $extensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file extension for a file.
|
||||
*
|
||||
* @param string $filename The name of the file
|
||||
* @return string The extension of the file
|
||||
*/
|
||||
public function get_extension(string $filename) {
|
||||
$dot = strrpos($filename, '.');
|
||||
if ($dot === false) {
|
||||
return '';
|
||||
}
|
||||
return strtolower(substr($filename, $dot));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first content bank plugin supports a file extension.
|
||||
*
|
||||
* @param string $extension Content file extension
|
||||
* @param \context $context $context Optional context to check (default null)
|
||||
* @return string contenttype name supports the file extension or null if the extension is not supported by any allowed plugin.
|
||||
*/
|
||||
public function get_extension_supporter(string $extension, \context $context = null): ?string {
|
||||
$supporters = $this->load_context_supported_extensions($context);
|
||||
if (array_key_exists($extension, $supporters)) {
|
||||
return $supporters[$extension];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
213
contentbank/classes/contenttype.php
Normal file
213
contentbank/classes/contenttype.php
Normal file
@ -0,0 +1,213 @@
|
||||
<?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 type 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 coding_exception;
|
||||
use moodle_url;
|
||||
|
||||
/**
|
||||
* Content type 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 contenttype {
|
||||
|
||||
/** Plugin implements uploading feature */
|
||||
const CAN_UPLOAD = 'upload';
|
||||
|
||||
/** @var context This content's context. **/
|
||||
protected $context = null;
|
||||
|
||||
/**
|
||||
* Content type constructor
|
||||
*
|
||||
* @param \context $context Optional context to check (default null)
|
||||
*/
|
||||
public function __construct(\context $context = null) {
|
||||
if (empty($context)) {
|
||||
$context = \context_system::instance();
|
||||
}
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills content_bank table with appropiate information.
|
||||
*
|
||||
* @param stdClass $content An optional content record compatible object (default null)
|
||||
* @return content Object with content bank information.
|
||||
*/
|
||||
public function create_content(\stdClass $content = null): ?content {
|
||||
global $USER, $DB;
|
||||
|
||||
$record = new \stdClass();
|
||||
$record->contenttype = $this->get_contenttype_name();
|
||||
$record->contextid = $this->context->id;
|
||||
$record->name = $content->name ?? '';
|
||||
$record->usercreated = $content->usercreated ?? $USER->id;
|
||||
$record->timecreated = time();
|
||||
$record->usermodified = $record->usercreated;
|
||||
$record->timemodified = $record->timecreated;
|
||||
$record->configdata = $content->configdata ?? '';
|
||||
$record->id = $DB->insert_record('contentbank_content', $record);
|
||||
if ($record->id) {
|
||||
$classname = '\\'.$record->contenttype.'\\content';
|
||||
return new $classname($record);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contenttype name of this content.
|
||||
*
|
||||
* @return string Content type of the current instance
|
||||
*/
|
||||
public function get_contenttype_name(): string {
|
||||
$classname = get_class($this);
|
||||
$contenttype = explode('\\', $classname);
|
||||
return array_shift($contenttype);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plugin name of the current instance.
|
||||
*
|
||||
* @return string Plugin name of the current instance
|
||||
*/
|
||||
public function get_plugin_name(): string {
|
||||
$contenttype = $this->get_contenttype_name();
|
||||
$plugin = explode('_', $contenttype);
|
||||
return array_pop($plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL where the content will be visualized.
|
||||
*
|
||||
* @param stdClass $record Th content to be displayed.
|
||||
* @return string URL where to visualize the given content.
|
||||
*/
|
||||
public function get_view_url(\stdClass $record): string {
|
||||
return new moodle_url('/contentbank/view.php', ['id' => $record->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML content to add to view.php visualizer.
|
||||
*
|
||||
* @param stdClass $record Th content to be displayed.
|
||||
* @return string HTML code to include in view.php.
|
||||
*/
|
||||
public function get_view_content(\stdClass $record): string {
|
||||
// Main contenttype class can visualize the content, but plugins could overwrite visualization.
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML code to render the icon for content bank contents.
|
||||
*
|
||||
* @param string $contentname The contentname to add as alt value to the icon.
|
||||
* @return string HTML code to render the icon
|
||||
*/
|
||||
public function get_icon(string $contentname): string {
|
||||
global $OUTPUT;
|
||||
return $OUTPUT->pix_icon('f/unknown-64', $contentname, 'moodle', ['class' => 'iconsize-big']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns user has access capability for the main content bank and the content itself (base on is_access_allowed from plugin).
|
||||
*
|
||||
* @return bool True if content could be accessed. False otherwise.
|
||||
*/
|
||||
final public function can_access(): bool {
|
||||
$classname = 'contenttype/'.$this->get_plugin_name();
|
||||
$capability = $classname.":access";
|
||||
$hascapabilities = has_capability('moodle/contentbank:access', $this->context)
|
||||
&& has_capability($capability, $this->context);
|
||||
return $hascapabilities && $this->is_access_allowed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns user has access capability for the content itself.
|
||||
*
|
||||
* @return bool True if content could be accessed. False otherwise.
|
||||
*/
|
||||
protected function is_access_allowed(): bool {
|
||||
// Plugins can overwrite this function to add any check they need.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user has permission to upload new content.
|
||||
*
|
||||
* @return bool True if content could be uploaded. False otherwise.
|
||||
*/
|
||||
final public function can_upload(): bool {
|
||||
if (!$this->is_feature_supported(self::CAN_UPLOAD)) {
|
||||
return false;
|
||||
}
|
||||
if (!$this->can_access()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$classname = 'contenttype/'.$this->get_plugin_name();
|
||||
$uploadcap = $classname.':upload';
|
||||
$hascapabilities = has_capability('moodle/contentbank:upload', $this->context)
|
||||
&& has_capability($uploadcap, $this->context);
|
||||
return $hascapabilities && $this->is_upload_allowed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns plugin allows uploading.
|
||||
*
|
||||
* @return bool True if plugin allows uploading. False otherwise.
|
||||
*/
|
||||
protected function is_upload_allowed(): bool {
|
||||
// Plugins can overwrite this function to add any check they need.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plugin supports the feature.
|
||||
*
|
||||
* @param string $feature Feature code e.g CAN_UPLOAD
|
||||
* @return bool True if content could be uploaded. False otherwise.
|
||||
*/
|
||||
final public function is_feature_supported(string $feature): bool {
|
||||
return in_array($feature, $this->get_implemented_features());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of implemented features by the plugins.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function get_implemented_features(): array;
|
||||
|
||||
/**
|
||||
* Return an array of extensions the plugins could manage.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function get_manageable_extensions(): array;
|
||||
}
|
71
contentbank/classes/helper.php
Normal file
71
contentbank/classes/helper.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Contains helper class for the content bank.
|
||||
*
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* Helper class for the content bank.
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class helper {
|
||||
|
||||
/**
|
||||
* Getting content bank page ready for the breadcrumbs.
|
||||
*
|
||||
* @param \context $context Context of the current page.
|
||||
* @param string $title Title of the current page.
|
||||
* @param bool $internal True if is an internal page, false otherwise.
|
||||
*/
|
||||
public static function get_page_ready(\context $context, string $title, bool $internal = false): void {
|
||||
global $PAGE, $DB;
|
||||
|
||||
$PAGE->set_context($context);
|
||||
$cburl = new \moodle_url('/contentbank/index.php', ['contextid' => $context->id]);
|
||||
|
||||
switch ($context->contextlevel) {
|
||||
case CONTEXT_COURSE:
|
||||
$courseid = $context->instanceid;
|
||||
$course = $DB->get_record('course', ['id' => $courseid], '*', MUST_EXIST);
|
||||
$PAGE->set_course($course);
|
||||
\navigation_node::override_active_url(new \moodle_url('/course/view.php', ['id' => $courseid]));
|
||||
$PAGE->navbar->add($title, $cburl);
|
||||
$PAGE->set_pagelayout('incourse');
|
||||
break;
|
||||
case CONTEXT_COURSECAT:
|
||||
$coursecat = $context->instanceid;
|
||||
\navigation_node::override_active_url(new \moodle_url('/course/index.php', ['categoryid' => $coursecat]));
|
||||
$PAGE->navbar->add($title, $cburl);
|
||||
$PAGE->set_pagelayout('coursecategory');
|
||||
break;
|
||||
default:
|
||||
if ($node = $PAGE->navigation->find('contentbank', \global_navigation::TYPE_CUSTOM)) {
|
||||
$node->make_active();
|
||||
}
|
||||
$PAGE->set_pagelayout('standard');
|
||||
}
|
||||
}
|
||||
}
|
96
contentbank/classes/output/bankcontent.php
Normal file
96
contentbank/classes/output/bankcontent.php
Normal file
@ -0,0 +1,96 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* core_contentbank specific renderers
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_contentbank\output;
|
||||
|
||||
use renderable;
|
||||
use templatable;
|
||||
use renderer_base;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class containing data for bank content
|
||||
*
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class bankcontent implements renderable, templatable {
|
||||
|
||||
/**
|
||||
* @var \core_contentbank\content[] Array of content bank contents.
|
||||
*/
|
||||
private $contents;
|
||||
|
||||
/**
|
||||
* @var array $toolbar object.
|
||||
*/
|
||||
private $toolbar;
|
||||
|
||||
/**
|
||||
* @var \context Given context. Null by default.
|
||||
*/
|
||||
private $context;
|
||||
|
||||
/**
|
||||
* Construct this renderable.
|
||||
*
|
||||
* @param \core_contentbank\content[] $contents Array of content bank contents.
|
||||
* @param array $toolbar List of content bank toolbar options.
|
||||
* @param \context $context Optional context to check (default null)
|
||||
*/
|
||||
public function __construct(array $contents, array $toolbar, \context $context = null) {
|
||||
$this->contents = $contents;
|
||||
$this->toolbar = $toolbar;
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the data.
|
||||
*
|
||||
* @param renderer_base $output
|
||||
* @return stdClass
|
||||
*/
|
||||
public function export_for_template(renderer_base $output): stdClass {
|
||||
$data = new stdClass();
|
||||
$contentdata = array();
|
||||
foreach ($this->contents as $content) {
|
||||
$record = $content->get_content();
|
||||
$managerclass = $content->get_content_type().'\\contenttype';
|
||||
if (class_exists($managerclass)) {
|
||||
$manager = new $managerclass($this->context);
|
||||
if ($manager->can_access()) {
|
||||
$name = $content->get_name();
|
||||
$contentdata[] = array(
|
||||
'name' => $name,
|
||||
'link' => $manager->get_view_url($record),
|
||||
'icon' => $manager->get_icon($name)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
$data->contents = $contentdata;
|
||||
$data->tools = $this->toolbar;
|
||||
return $data;
|
||||
}
|
||||
}
|
129
contentbank/classes/privacy/provider.php
Normal file
129
contentbank/classes/privacy/provider.php
Normal file
@ -0,0 +1,129 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Privacy provider implementation for core_contentbank.
|
||||
*
|
||||
* @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\privacy;
|
||||
|
||||
use core_privacy\local\metadata\collection;
|
||||
use core_privacy\local\request\approved_contextlist;
|
||||
use core_privacy\local\request\approved_userlist;
|
||||
use core_privacy\local\request\contextlist;
|
||||
use core_privacy\local\request\userlist;
|
||||
|
||||
/**
|
||||
* Privacy provider implementation for core_contentbank.
|
||||
*
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider implements
|
||||
\core_privacy\local\metadata\provider,
|
||||
\core_privacy\local\request\core_userlist_provider,
|
||||
\core_privacy\local\request\plugin\provider {
|
||||
|
||||
/**
|
||||
* Returns metadata.
|
||||
* TODO: MDL-67798.
|
||||
*
|
||||
* @param collection $collection The initialised collection to add items to.
|
||||
* @return collection A listing of user data stored through this system.
|
||||
*/
|
||||
public static function get_metadata(collection $collection) : collection {
|
||||
// We are not implementing a proper privacy provider for now.
|
||||
// A right privacy provider will be implemented in MDL-67798.
|
||||
|
||||
$collection->add_database_table('contentbank_content', [
|
||||
'usercreated' => 'privacy:metadata:content:usercreated',
|
||||
'usermodified' => 'privacy:metadata:content:usermodified',
|
||||
], 'privacy:metadata:userid');
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: MDL-67798.
|
||||
*
|
||||
* @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
|
||||
*/
|
||||
public static function get_users_in_context(userlist $userlist) {
|
||||
// We are not implementing a proper privacy provider for now.
|
||||
// A right privacy provider will be implemented in MDL-67798.
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: MDL-67798.
|
||||
*
|
||||
* @param approved_userlist $userlist The approved context and user information to delete information for.
|
||||
*/
|
||||
public static function delete_data_for_users(approved_userlist $userlist) {
|
||||
// We are not implementing a proper privacy provider for now.
|
||||
// A right privacy provider will be implemented in MDL-67798.
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: MDL-67798.
|
||||
* Get the list of contexts that contain user information for the specified user.
|
||||
*
|
||||
* @param int $userid The user to search.
|
||||
* @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
|
||||
*/
|
||||
public static function get_contexts_for_userid(int $userid) : contextlist {
|
||||
// We are not implementing a proper privacy provider for now.
|
||||
// A right privacy provider will be implemented in MDL-67798.
|
||||
|
||||
return (new contextlist());
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: MDL-67798.
|
||||
* Export all user data for the specified user, in the specified contexts.
|
||||
*
|
||||
* @param approved_contextlist $contextlist The approved contexts to export information for.
|
||||
*/
|
||||
public static function export_user_data(approved_contextlist $contextlist) {
|
||||
// We are not implementing a proper privacy provider for now.
|
||||
// A right privacy provider will be implemented in MDL-67798.
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: MDL-67798.
|
||||
* Delete all data for all users in the specified context.
|
||||
*
|
||||
* @param context $context The specific context to delete data for.
|
||||
*/
|
||||
public static function delete_data_for_all_users_in_context(\context $context) {
|
||||
// We are not implementing a proper privacy provider for now.
|
||||
// A right privacy provider will be implemented in MDL-67798.
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: MDL-67798.
|
||||
* Delete all user data for the specified user, in the specified contexts.
|
||||
*
|
||||
* @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
|
||||
*/
|
||||
public static function delete_data_for_user(approved_contextlist $contextlist) {
|
||||
// We are not implementing a proper privacy provider for now.
|
||||
// A right privacy provider will be implemented in MDL-67798.
|
||||
}
|
||||
}
|
38
contentbank/contenttype/h5p/classes/content.php
Normal file
38
contentbank/contenttype/h5p/classes/content.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* H5P Content manager class
|
||||
*
|
||||
* @package contenttype_h5p
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace contenttype_h5p;
|
||||
|
||||
use stdClass;
|
||||
use html_writer;
|
||||
|
||||
/**
|
||||
* H5P Content manager class
|
||||
*
|
||||
* @package contenttype_h5p
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class content extends \core_contentbank\content {
|
||||
}
|
90
contentbank/contenttype/h5p/classes/contenttype.php
Normal file
90
contentbank/contenttype/h5p/classes/contenttype.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* H5P content type manager class
|
||||
*
|
||||
* @package contenttype_h5p
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace contenttype_h5p;
|
||||
|
||||
use stdClass;
|
||||
use html_writer;
|
||||
|
||||
/**
|
||||
* H5P content bank manager class
|
||||
*
|
||||
* @package contenttype_h5p
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class contenttype extends \core_contentbank\contenttype {
|
||||
|
||||
/**
|
||||
* Returns the HTML content to add to view.php visualizer.
|
||||
*
|
||||
* @param stdClass $record Th content to be displayed.
|
||||
* @return string HTML code to include in view.php.
|
||||
*/
|
||||
public function get_view_content(\stdClass $record): string {
|
||||
$content = new content($record);
|
||||
$fileurl = $content->get_file_url();
|
||||
$html = html_writer::tag('h2', $content->get_name());
|
||||
$html .= \core_h5p\player::display($fileurl, new \stdClass(), true);
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML code to render the icon for H5P content types.
|
||||
*
|
||||
* @param string $contentname The contentname to add as alt value to the icon.
|
||||
* @return string HTML code to render the icon
|
||||
*/
|
||||
public function get_icon(string $contentname): string {
|
||||
global $OUTPUT;
|
||||
return $OUTPUT->pix_icon('f/h5p-64', $contentname, 'moodle', ['class' => 'iconsize-big']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of implemented features by this plugin.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_implemented_features(): array {
|
||||
return [self::CAN_UPLOAD];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of extensions this contenttype could manage.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_manageable_extensions(): array {
|
||||
return ['.h5p'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns user has access capability for the content itself.
|
||||
*
|
||||
* @return bool True if content could be accessed. False otherwise.
|
||||
*/
|
||||
protected function is_access_allowed(): bool {
|
||||
return true;
|
||||
}
|
||||
}
|
44
contentbank/contenttype/h5p/classes/privacy/provider.php
Normal file
44
contentbank/contenttype/h5p/classes/privacy/provider.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Privacy provider implementation for core_contentbank.
|
||||
*
|
||||
* @package contenttype_h5p
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace contenttype_h5p\privacy;
|
||||
|
||||
/**
|
||||
* Privacy provider implementation for contenttype_h5p.
|
||||
*
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider implements \core_privacy\local\metadata\null_provider {
|
||||
|
||||
/**
|
||||
* Get the language string identifier with the component's language
|
||||
* file to explain why this plugin stores no data.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_reason() : string {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
47
contentbank/contenttype/h5p/db/access.php
Normal file
47
contentbank/contenttype/h5p/db/access.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* H5P content bank contenttype capabilities.
|
||||
*
|
||||
* @package contenttype_h5p
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$capabilities = [
|
||||
'contenttype/h5p:access' => array(
|
||||
'captype' => 'read',
|
||||
'contextlevel' => CONTEXT_COURSE,
|
||||
'archetypes' => array(
|
||||
'manager' => CAP_ALLOW,
|
||||
'coursecreator' => CAP_ALLOW,
|
||||
'editingteacher' => CAP_ALLOW,
|
||||
)
|
||||
),
|
||||
'contenttype/h5p:upload' => [
|
||||
'riskbitmask' => RISK_SPAM,
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_COURSE,
|
||||
'archetypes' => [
|
||||
'manager' => CAP_ALLOW,
|
||||
'coursecreator' => CAP_ALLOW,
|
||||
'editingteacher' => CAP_ALLOW,
|
||||
]
|
||||
],
|
||||
];
|
29
contentbank/contenttype/h5p/lang/en/contenttype_h5p.php
Normal file
29
contentbank/contenttype/h5p/lang/en/contenttype_h5p.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Strings for plugin 'contenttype_h5p'
|
||||
*
|
||||
* @package contenttype_h5p
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['pluginname'] = 'H5P';
|
||||
$string['pluginname_help'] = 'Content bank to upload and share H5P content';
|
||||
$string['privacy:metadata'] = 'The H5P content bank plugin does not store any personal data.';
|
||||
$string['h5p:access'] = 'Access to H5P content in the content bank';
|
||||
$string['h5p:upload'] = 'Upload a new H5P content';
|
@ -0,0 +1,73 @@
|
||||
@core @core_contentbank @contenttype_h5p @_file_upload @_switch_iframe @javascript
|
||||
Feature: H5P file upload to content bank for admins
|
||||
In order import new H5P content to content bank
|
||||
As an admin
|
||||
I need to be able to upload a new .h5p file to content bank
|
||||
|
||||
Background:
|
||||
Given I log in as "admin"
|
||||
And I follow "Manage private files..."
|
||||
And I upload "h5p/tests/fixtures/filltheblanks.h5p" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
And I press "Customise this page"
|
||||
And I add the "Navigation" block if not present
|
||||
And I expand "Site pages" node
|
||||
And I click on "Content bank" "link"
|
||||
|
||||
Scenario: Admins can upload .h5p extension files to content bank
|
||||
Given I should not see "filltheblanks.h5p"
|
||||
When I click on "Upload" "link"
|
||||
And I click on "Choose a file..." "button"
|
||||
And I click on "Private files" "link" in the ".fp-repo-area" "css_element"
|
||||
And I click on "filltheblanks.h5p" "link"
|
||||
And I click on "Select this file" "button"
|
||||
And I click on "Save changes" "button"
|
||||
And I wait until the page is ready
|
||||
Then I should see "filltheblanks.h5p"
|
||||
|
||||
Scenario: Admins can see uploaded H5P contents
|
||||
Given I should not see "filltheblanks.h5p"
|
||||
When I click on "Upload" "link"
|
||||
And I click on "Choose a file..." "button"
|
||||
And I click on "Private files" "link" in the ".fp-repo-area" "css_element"
|
||||
And I click on "filltheblanks.h5p" "link"
|
||||
And I click on "Select this file" "button"
|
||||
And I click on "Save changes" "button"
|
||||
And I wait until the page is ready
|
||||
And I click on "filltheblanks.h5p" "link"
|
||||
And I switch to "h5p-player" class iframe
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
Then I should see "Of which countries"
|
||||
|
||||
Scenario: Users can't see content managed by disabled plugins
|
||||
Given I click on "Upload" "link"
|
||||
And I click on "Choose a file..." "button"
|
||||
And I click on "Private files" "link" in the ".fp-repo-area" "css_element"
|
||||
And I click on "filltheblanks.h5p" "link"
|
||||
And I click on "Select this file" "button"
|
||||
And I click on "Save changes" "button"
|
||||
And I wait until the page is ready
|
||||
And I should see "filltheblanks.h5p"
|
||||
And I navigate to "Plugins > Content bank > Manage content bank content types" in site administration
|
||||
And I click on "Disable" "icon" in the "H5P" "table_row"
|
||||
And I wait until the page is ready
|
||||
When I click on "Content bank" "link"
|
||||
Then I should not see "filltheblanks.h5p"
|
||||
|
||||
Scenario: Contents in a context are not available from other contexts
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
When I click on "Upload" "link"
|
||||
And I click on "Choose a file..." "button"
|
||||
And I click on "Private files" "link" in the ".fp-repo-area" "css_element"
|
||||
And I click on "filltheblanks.h5p" "link"
|
||||
And I click on "Select this file" "button"
|
||||
And I click on "Save changes" "button"
|
||||
And I wait until the page is ready
|
||||
Then I should see "filltheblanks.h5p"
|
||||
And I am on "Course 1" course homepage
|
||||
And I add the "Navigation" block if not present
|
||||
And I expand "Site pages" node
|
||||
And I click on "Content bank" "link"
|
||||
And I should not see "filltheblanks.h5p"
|
@ -0,0 +1,73 @@
|
||||
@core @core_contentbank @contenttype_h5p @_file_upload @_switch_iframe @javascript
|
||||
Feature: H5P file upload to content bank for non admins
|
||||
In order import new H5P content to content bank
|
||||
As an admin
|
||||
I need to be able to upload a new .h5p file to content bank
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
| teacher2 | Teacher | 2 | teacher2@example.com |
|
||||
And the following "categories" exist:
|
||||
| name | category | idnumber |
|
||||
| Cat 1 | 0 | CAT1 |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | CAT1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| teacher2 | C1 | editingteacher |
|
||||
And I log in as "teacher1"
|
||||
And I follow "Manage private files..."
|
||||
And I upload "h5p/tests/fixtures/filltheblanks.h5p" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
|
||||
Scenario: Teachers can not access system level content bank
|
||||
Given I press "Customise this page"
|
||||
And I add the "Navigation" block if not present
|
||||
When I expand "Site pages" node
|
||||
Then I should not see "Content bank"
|
||||
|
||||
Scenario: Teachers can access course level content bank
|
||||
Given I am on "Course 1" course homepage with editing mode on
|
||||
And I add the "Navigation" block if not present
|
||||
When I expand "Site pages" node
|
||||
Then I should see "Content bank"
|
||||
|
||||
Scenario: Teachers can upload .h5p extension files to course content bank
|
||||
Given I am on "Course 1" course homepage with editing mode on
|
||||
And I add the "Navigation" block if not present
|
||||
When I expand "Site pages" node
|
||||
And I click on "Content bank" "link"
|
||||
Then I should not see "filltheblanks.h5p"
|
||||
And I click on "Upload" "link"
|
||||
And I click on "Choose a file..." "button"
|
||||
And I click on "Private files" "link" in the ".fp-repo-area" "css_element"
|
||||
And I click on "filltheblanks.h5p" "link"
|
||||
And I click on "Select this file" "button"
|
||||
And I click on "Save changes" "button"
|
||||
And I wait until the page is ready
|
||||
And I should see "filltheblanks.h5p"
|
||||
|
||||
Scenario: Other teachers can see uploaded H5P contents
|
||||
Given I am on "Course 1" course homepage with editing mode on
|
||||
And I add the "Navigation" block if not present
|
||||
When I expand "Site pages" node
|
||||
And I click on "Content bank" "link"
|
||||
And I click on "Upload" "link"
|
||||
And I click on "Choose a file..." "button"
|
||||
And I click on "Private files" "link" in the ".fp-repo-area" "css_element"
|
||||
And I click on "filltheblanks.h5p" "link"
|
||||
And I click on "Select this file" "button"
|
||||
And I click on "Save changes" "button"
|
||||
And I wait until the page is ready
|
||||
And I should see "filltheblanks.h5p"
|
||||
And I log out
|
||||
When I log in as "teacher2"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I add the "Navigation" block if not present
|
||||
And I expand "Site pages" node
|
||||
And I click on "Content bank" "link"
|
||||
Then I should see "filltheblanks.h5p"
|
69
contentbank/contenttype/h5p/tests/content_h5p_test.php
Normal file
69
contentbank/contenttype/h5p/tests/content_h5p_test.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Test for H5P content bank plugin.
|
||||
*
|
||||
* @package contenttype_h5p
|
||||
* @category test
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test for H5P content bank plugin.
|
||||
*
|
||||
* @package contenttype_h5p
|
||||
* @category test
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \contenttype_h5p\content
|
||||
*/
|
||||
class contenttype_h5p_content_plugin_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Tests for uploaded file.
|
||||
*
|
||||
* @covers ::get_file
|
||||
*/
|
||||
public function test_upload_file() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Create content.
|
||||
$record = new stdClass();
|
||||
$record->name = 'Test content';
|
||||
$record->configdata = '';
|
||||
$contenttype = new \contenttype_h5p\contenttype(context_system::instance());
|
||||
$content = $contenttype->create_content($record);
|
||||
|
||||
// Create a dummy file.
|
||||
$filename = 'content.h5p';
|
||||
$dummy = array(
|
||||
'contextid' => \context_system::instance()->id,
|
||||
'component' => 'contentbank',
|
||||
'filearea' => 'public',
|
||||
'itemid' => $content->get_id(),
|
||||
'filepath' => '/',
|
||||
'filename' => $filename
|
||||
);
|
||||
$fs = get_file_storage();
|
||||
$fs->create_file_from_string($dummy, 'dummy content');
|
||||
|
||||
$file = $content->get_file();
|
||||
$this->assertInstanceOf(\stored_file::class, $file);
|
||||
$this->assertEquals($filename, $file->get_filename());
|
||||
}
|
||||
}
|
67
contentbank/contenttype/h5p/tests/contenttype_h5p_test.php
Normal file
67
contentbank/contenttype/h5p/tests/contenttype_h5p_test.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Test for H5P content bank plugin.
|
||||
*
|
||||
* @package contenttype_h5p
|
||||
* @category test
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test for H5P content bank plugin.
|
||||
*
|
||||
* @package contenttype_h5p
|
||||
* @category test
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \contenttype_h5p\contenttype
|
||||
*/
|
||||
class contenttype_h5p_contenttype_plugin_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Tests can_upload behavior.
|
||||
*
|
||||
* @covers ::can_upload
|
||||
*/
|
||||
public function test_can_upload() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$systemcontext = \context_system::instance();
|
||||
$systemtype = new \contenttype_h5p\contenttype($systemcontext);
|
||||
|
||||
// Admins can upload.
|
||||
$this->setAdminUser();
|
||||
$this->assertTrue($systemtype->can_upload());
|
||||
|
||||
// Teacher can upload in the course but not at system level.
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
|
||||
$coursecontext = \context_course::instance($course->id);
|
||||
$coursetype = new \contenttype_h5p\contenttype($coursecontext);
|
||||
$this->setUser($teacher);
|
||||
$this->assertTrue($coursetype->can_upload());
|
||||
$this->assertFalse($systemtype->can_upload());
|
||||
|
||||
// Users can't upload.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
$this->assertFalse($coursetype->can_upload());
|
||||
$this->assertFalse($systemtype->can_upload());
|
||||
}
|
||||
}
|
29
contentbank/contenttype/h5p/version.php
Normal file
29
contentbank/contenttype/h5p/version.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Version details
|
||||
*
|
||||
* @package contenttype_h5p
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2020041500.00; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2020041500.00; // Requires this Moodle version
|
||||
$plugin->component = 'contenttype_h5p'; // Full name of the plugin (used for diagnostics).
|
73
contentbank/files_form.php
Normal file
73
contentbank/files_form.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Upload files to content bank form
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once("$CFG->libdir/formslib.php");
|
||||
|
||||
/**
|
||||
* Class contentbank_files_form
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class contentbank_files_form extends moodleform {
|
||||
|
||||
/**
|
||||
* Add elements to this form.
|
||||
*/
|
||||
public function definition() {
|
||||
$mform = $this->_form;
|
||||
|
||||
$mform->addElement('hidden', 'contextid', $this->_customdata['contextid']);
|
||||
$mform->setType('contextid', PARAM_INT);
|
||||
|
||||
$options = $this->_customdata['options'];
|
||||
$mform->addElement('filepicker', 'file', get_string('file', 'core_contentbank'), null, $options);
|
||||
$mform->addHelpButton('file', 'file', 'core_contentbank');
|
||||
$mform->addRule('file', null, 'required');
|
||||
|
||||
$this->add_action_buttons(true, get_string('savechanges'));
|
||||
|
||||
$data = $this->_customdata['data'];
|
||||
$this->set_data($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate incoming data.
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $files
|
||||
* @return array
|
||||
*/
|
||||
public function validation($data, $files) {
|
||||
$errors = array();
|
||||
$draftitemid = $data['file'];
|
||||
if (file_is_draft_area_limit_reached($draftitemid, $this->_customdata['options']['areamaxbytes'])) {
|
||||
$errors['file'] = get_string('userquotalimit', 'error');
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
}
|
81
contentbank/index.php
Normal file
81
contentbank/index.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* List content in content bank.
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require('../config.php');
|
||||
|
||||
require_login();
|
||||
|
||||
$contextid = optional_param('contextid', \context_system::instance()->id, PARAM_INT);
|
||||
$context = context::instance_by_id($contextid, MUST_EXIST);
|
||||
|
||||
require_capability('moodle/contentbank:access', $context);
|
||||
|
||||
$title = get_string('contentbank');
|
||||
\core_contentbank\helper::get_page_ready($context, $title);
|
||||
if ($PAGE->course) {
|
||||
require_login($PAGE->course->id);
|
||||
}
|
||||
$PAGE->set_url('/contentbank/index.php');
|
||||
$PAGE->set_context($context);
|
||||
$PAGE->set_title($title);
|
||||
$PAGE->set_heading($title);
|
||||
$PAGE->set_pagetype('contenbank');
|
||||
|
||||
// Get all contents managed by active plugins to render.
|
||||
$foldercontents = array();
|
||||
$contents = $DB->get_records('contentbank_content', ['contextid' => $contextid]);
|
||||
foreach ($contents as $content) {
|
||||
$plugin = core_plugin_manager::instance()->get_plugin_info($content->contenttype);
|
||||
if (!$plugin || !$plugin->is_enabled()) {
|
||||
continue;
|
||||
}
|
||||
$contentclass = "\\$content->contenttype\\content";
|
||||
if (class_exists($contentclass)) {
|
||||
$contentmanager = new $contentclass($content);
|
||||
if ($contentmanager->can_view()) {
|
||||
$foldercontents[] = $contentmanager;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the toolbar ready.
|
||||
$toolbar = array ();
|
||||
if (has_capability('moodle/contentbank:upload', $context)) {
|
||||
// Don' show upload button if there's no plugin to support any file extension.
|
||||
$cb = new \core_contentbank\contentbank();
|
||||
$accepted = $cb->get_supported_extensions_as_string($context);
|
||||
if (!empty($accepted)) {
|
||||
$importurl = new moodle_url('/contentbank/upload.php', ['contextid' => $contextid]);
|
||||
$toolbar[] = array('name' => 'Upload', 'link' => $importurl, 'icon' => 'i/upload');
|
||||
}
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->box_start('generalbox');
|
||||
|
||||
$folder = new \core_contentbank\output\bankcontent($foldercontents, $toolbar, $context);
|
||||
echo $OUTPUT->render($folder);
|
||||
|
||||
echo $OUTPUT->box_end();
|
||||
echo $OUTPUT->footer();
|
73
contentbank/templates/bankcontent.mustache
Normal file
73
contentbank/templates/bankcontent.mustache
Normal file
@ -0,0 +1,73 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template core_contentbank/list
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"contents": [
|
||||
{
|
||||
"name": "accordion.h5p",
|
||||
"link": "http://something/contentbank/contenttype/h5p/view.php?url=http://something/pluginfile.php/1/contentbank/public/accordion.h5p",
|
||||
"icon" : "<img class='icon iconsize-big' alt='accordion.h5p' aria-hidden='true' src='http://something/theme/image.php/boost/core/1581597850/f/h5p-64'>"
|
||||
},
|
||||
{
|
||||
"name": "resume.pdf",
|
||||
"icon": "<img class='icon iconsize-big' alt='resume.pdf' aria-hidden='true' src='http://something/theme/image.php/boost/core/1584597850/f/pdf-64'>"
|
||||
}
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"name": "Upload",
|
||||
"link": "http://something/contentbank/contenttype/h5p/view.php?url=http://something/pluginfile.php/1/contentbank/public/accordion.h5p",
|
||||
"icon" : "i/upload"
|
||||
},
|
||||
{
|
||||
"icon": "i/export"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}}
|
||||
{{>core_contentbank/toolbar}}
|
||||
<div class="content-bank-container card">
|
||||
<div class="content-bank">
|
||||
<div class="cb-navbar">
|
||||
{{#pix}} i/folder {{/pix}}
|
||||
</div>
|
||||
<div class="cb-content-wrapper">
|
||||
{{#contents}}
|
||||
<div class="cb-content">
|
||||
<div class="cb-iconview">
|
||||
<div class="cb-file text-center position-relative">
|
||||
{{#link}}<a href="{{{ link }}}">{{/link}}
|
||||
<div style="position:relative;">
|
||||
<div class="cb-thumbnail text-center d-block" style="width: 110px; height: 110px;">
|
||||
{{{ icon }}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="cb-contentname-field position-absolute overflow-visible">
|
||||
<div class="cb-contentname text-truncate" style="width: 112px;">{{{ name }}}</div>
|
||||
</div>
|
||||
{{#link}}</a>{{/link}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/contents}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
47
contentbank/templates/toolbar.mustache
Normal file
47
contentbank/templates/toolbar.mustache
Normal file
@ -0,0 +1,47 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template core_contentbank/toolbar
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"tools": [
|
||||
{
|
||||
"name": "Upload",
|
||||
"link": "http://something/contentbank/contenttype/h5p/view.php?url=http://something/pluginfile.php/1/contentbank/public/accordion.h5p",
|
||||
"icon" : "i/upload"
|
||||
},
|
||||
{
|
||||
"icon": "i/export"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}}
|
||||
<div class="content-bank-toolbar card border-0 mb-3">
|
||||
<div class="content-bank">
|
||||
<div class="cb-toolbar float-sm-right">
|
||||
{{#tools}}
|
||||
{{#link}}<a href="{{{ link }}}" title="{{{ name }}}">{{/link}}
|
||||
<div class="cb-tool btn btn-secondary btn-sm">
|
||||
{{#pix}} {{{ icon }}} {{/pix}}
|
||||
</div>
|
||||
{{#link}}</a>{{/link}}
|
||||
{{/tools}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
29
contentbank/tests/behat/access_permissions.feature
Normal file
29
contentbank/tests/behat/access_permissions.feature
Normal file
@ -0,0 +1,29 @@
|
||||
@core @core_contentbank
|
||||
Feature: Access permission to content Bank
|
||||
In order to control access to content bank
|
||||
As an admin
|
||||
I need to be able to configure users' permissions
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | user1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
|
||||
Scenario: Admins access content bank
|
||||
Given I log in as "admin"
|
||||
Then "Content bank" "link" should exist
|
||||
|
||||
Scenario: Editing teachers can access content bank at course level
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
Then "Content bank" "link" should exist
|
||||
|
||||
Scenario: Editing teachers can't access content bank at system level
|
||||
Given I log in as "teacher1"
|
||||
Then "Content bank" "link" should not exist
|
107
contentbank/tests/content_test.php
Normal file
107
contentbank/tests/content_test.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Test for content bank contenttype class.
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @category test
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_contentbank;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_contenttype.php');
|
||||
require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_content.php');
|
||||
|
||||
use stdClass;
|
||||
use context_system;
|
||||
use contenttype_testable\contenttype as contenttype;
|
||||
/**
|
||||
* Test for content bank contenttype class.
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @category test
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \core_contentbank\content
|
||||
*
|
||||
*/
|
||||
class core_contenttype_content_testcase extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Tests for behaviour of get_name().
|
||||
*
|
||||
* @covers ::get_name
|
||||
*/
|
||||
public function test_get_name() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Create content.
|
||||
$record = new stdClass();
|
||||
$record->name = 'Test content';
|
||||
$record->configdata = '';
|
||||
|
||||
$contenttype = new contenttype(context_system::instance());
|
||||
$content = $contenttype->create_content($record);
|
||||
$this->assertEquals($record->name, $content->get_name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for behaviour of get_content_type().
|
||||
*
|
||||
* @covers ::get_content_type
|
||||
*/
|
||||
public function test_get_content_type() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Create content.
|
||||
$record = new stdClass();
|
||||
$record->name = 'Test content';
|
||||
$record->configdata = '';
|
||||
|
||||
$contenttype = new contenttype(context_system::instance());
|
||||
$content = $contenttype->create_content($record);
|
||||
$this->assertEquals('contenttype_testable', $content->get_content_type());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for 'configdata' behaviour.
|
||||
*
|
||||
* @covers ::set_configdata
|
||||
*/
|
||||
public function test_configdata_changes() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$configdata = "{img: 'icon.svg'}";
|
||||
|
||||
// Create content.
|
||||
$record = new stdClass();
|
||||
$record->configdata = $configdata;
|
||||
|
||||
$contenttype = new contenttype(context_system::instance());
|
||||
$content = $contenttype->create_content($record);
|
||||
$this->assertEquals($configdata, $content->get_configdata());
|
||||
|
||||
$configdata = "{alt: 'Name'}";
|
||||
$content->set_configdata($configdata);
|
||||
$this->assertEquals($configdata, $content->get_configdata());
|
||||
}
|
||||
}
|
178
contentbank/tests/contentbank_test.php
Normal file
178
contentbank/tests/contentbank_test.php
Normal file
@ -0,0 +1,178 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Test for extensions manager.
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @category test
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_contenttype.php');
|
||||
|
||||
/**
|
||||
* Test for extensions manager.
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @category test
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \core_contentbank\contentbank
|
||||
*/
|
||||
class core_contentbank_testcase extends advanced_testcase {
|
||||
/**
|
||||
* Data provider for test_get_extension_supporter.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_extension_provider() {
|
||||
return [
|
||||
'H5P file' => ['something.h5p', '.h5p'],
|
||||
'PDF file' => ['something.pdf', '.pdf']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for get_extension() function.
|
||||
*
|
||||
* @dataProvider get_extension_provider
|
||||
* @param string $filename The filename given
|
||||
* @param string $expected The extension of the file
|
||||
*
|
||||
* @covers ::get_extension
|
||||
*/
|
||||
public function test_get_extension(string $filename, string $expected) {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$cb = new \core_contentbank\contentbank();
|
||||
|
||||
$extension = $cb->get_extension($filename);
|
||||
$this->assertEquals($expected, $extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_load_context_supported_extensions.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_extension_supporters_provider() {
|
||||
return [
|
||||
'H5P first' => [['.h5p' => ['h5p', 'testable']], '.h5p', 'h5p'],
|
||||
'Testable first (but upload not implemented)' => [['.h5p' => ['testable', 'h5p']], '.h5p', 'h5p'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for get_extension_supporter() function with admin permissions.
|
||||
*
|
||||
* @dataProvider get_extension_supporters_provider
|
||||
* @param array $supporters The content type plugin supporters for each extension
|
||||
* @param string $extension The extension of the file given
|
||||
* @param string $expected The supporter contenttype of the file
|
||||
*
|
||||
* @covers ::load_context_supported_extensions
|
||||
*/
|
||||
public function test_get_extension_supporter_for_admins(array $supporters, string $extension, string $expected) {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$cb = new \core_contentbank\contentbank();
|
||||
$expectedsupporters = [$extension => $expected];
|
||||
|
||||
$systemcontext = context_system::instance();
|
||||
|
||||
// All contexts allowed for admins.
|
||||
$this->setAdminUser();
|
||||
$contextsupporters = $cb->load_context_supported_extensions($systemcontext);
|
||||
$this->assertEquals($expectedsupporters, $contextsupporters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for get_extension_supporter() function with user default permissions.
|
||||
*
|
||||
* @dataProvider get_extension_supporters_provider
|
||||
* @param array $supporters The content type plugin supporters for each extension
|
||||
* @param string $extension The extension of the file given
|
||||
* @param string $expected The supporter contenttype of the file
|
||||
*
|
||||
* @covers ::load_context_supported_extensions
|
||||
*/
|
||||
public function test_get_extension_supporter_for_users(array $supporters, string $extension, string $expected) {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$cb = new \core_contentbank\contentbank();
|
||||
$systemcontext = context_system::instance();
|
||||
|
||||
// Set a user with no permissions.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
|
||||
// Users with no capabilities can't upload content.
|
||||
$contextsupporters = $cb->load_context_supported_extensions($systemcontext);
|
||||
$this->assertEquals([], $contextsupporters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for get_extension_supporter() function with teacher defaul permissions.
|
||||
*
|
||||
* @dataProvider get_extension_supporters_provider
|
||||
* @param array $supporters The content type plugin supporters for each extension
|
||||
* @param string $extension The extension of the file given
|
||||
* @param string $expected The supporter contenttype of the file
|
||||
*
|
||||
* @covers ::load_context_supported_extensions
|
||||
*/
|
||||
public function test_get_extension_supporter_for_teachers(array $supporters, string $extension, string $expected) {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$cb = new \core_contentbank\contentbank();
|
||||
$expectedsupporters = [$extension => $expected];
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
|
||||
$this->setUser($teacher);
|
||||
$coursecontext = context_course::instance($course->id);
|
||||
|
||||
// Teachers has permission in their context to upload supported by H5P content type.
|
||||
$contextsupporters = $cb->load_context_supported_extensions($coursecontext);
|
||||
$this->assertEquals($expectedsupporters, $contextsupporters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for get_extension_supporter() function.
|
||||
*
|
||||
* @dataProvider get_extension_supporters_provider
|
||||
* @param array $supporters The content type plugin supporters for each extension
|
||||
* @param string $extension The extension of the file given
|
||||
* @param string $expected The supporter contenttype of the file
|
||||
*
|
||||
* @covers ::get_extension_supporter
|
||||
*/
|
||||
public function test_get_extension_supporter(array $supporters, string $extension, string $expected) {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$cb = new \core_contentbank\contentbank();
|
||||
$systemcontext = context_system::instance();
|
||||
$this->setAdminUser();
|
||||
|
||||
$supporter = $cb->get_extension_supporter($extension, $systemcontext);
|
||||
$this->assertEquals($expected, $supporter);
|
||||
}
|
||||
}
|
160
contentbank/tests/contenttype_test.php
Normal file
160
contentbank/tests/contenttype_test.php
Normal file
@ -0,0 +1,160 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Test for content bank contenttype class.
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @category test
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_contentbank;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_contenttype.php');
|
||||
require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_content.php');
|
||||
|
||||
use stdClass;
|
||||
use context_system;
|
||||
use contenttype_testable\contenttype as contenttype;
|
||||
/**
|
||||
* Test for content bank contenttype class.
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @category test
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \core_contentbank\contenttype
|
||||
*
|
||||
*/
|
||||
class core_contenttype_contenttype_testcase extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Tests get_contenttype_name result.
|
||||
*
|
||||
* @covers ::get_contenttype_name
|
||||
*/
|
||||
public function test_get_contenttype_name() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$systemcontext = \context_system::instance();
|
||||
$testable = new contenttype($systemcontext);
|
||||
|
||||
$this->assertEquals('contenttype_testable', $testable->get_contenttype_name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests get_plugin_name result.
|
||||
*
|
||||
* @covers ::get_plugin_name
|
||||
*/
|
||||
public function test_get_plugin_name() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$systemcontext = \context_system::instance();
|
||||
$testable = new contenttype($systemcontext);
|
||||
|
||||
$this->assertEquals('testable', $testable->get_plugin_name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests get_icon result.
|
||||
*
|
||||
* @covers ::get_icon
|
||||
*/
|
||||
public function test_get_icon() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$systemcontext = \context_system::instance();
|
||||
$testable = new contenttype($systemcontext);
|
||||
$icon = $testable->get_icon('new content');
|
||||
$this->assertContains('archive', $icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests is_feature_supported behavior .
|
||||
*
|
||||
* @covers ::is_feature_supported
|
||||
*/
|
||||
public function test_is_feature_supported() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$systemcontext = \context_system::instance();
|
||||
$testable = new contenttype($systemcontext);
|
||||
|
||||
$this->assertTrue($testable->is_feature_supported(contenttype::CAN_TEST));
|
||||
$this->assertFalse($testable->is_feature_supported(contenttype::CAN_UPLOAD));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests can_upload behavior with no implemented upload feature.
|
||||
*
|
||||
* @covers ::can_upload
|
||||
*/
|
||||
public function test_no_upload_feature_supported() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$systemcontext = \context_system::instance();
|
||||
$testable = new contenttype($systemcontext);
|
||||
|
||||
$this->setAdminUser();
|
||||
$this->assertFalse($testable->is_feature_supported(contenttype::CAN_UPLOAD));
|
||||
$this->assertFalse($testable->can_upload());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create_content() with empty data.
|
||||
*
|
||||
* @covers ::create_content
|
||||
*/
|
||||
public function test_create_empty_content() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Create empty content.
|
||||
$record = new stdClass();
|
||||
|
||||
$contenttype = new contenttype(context_system::instance());
|
||||
$content = $contenttype->create_content($record);
|
||||
|
||||
$this->assertEquals('contenttype_testable', $content->get_content_type());
|
||||
$this->assertInstanceOf('\\contenttype_testable\\content', $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for behaviour of create_content() with data.
|
||||
*
|
||||
* @covers ::create_content
|
||||
*/
|
||||
public function test_create_content() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Create content.
|
||||
$record = new stdClass();
|
||||
$record->name = 'Test content';
|
||||
$record->configdata = '';
|
||||
$record->contenttype = '';
|
||||
|
||||
$contenttype = new contenttype(context_system::instance());
|
||||
$content = $contenttype->create_content($record);
|
||||
|
||||
$this->assertEquals('contenttype_testable', $content->get_content_type());
|
||||
$this->assertInstanceOf('\\contenttype_testable\\content', $content);
|
||||
}
|
||||
}
|
36
contentbank/tests/fixtures/testable_content.php
vendored
Normal file
36
contentbank/tests/fixtures/testable_content.php
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Testable content plugin class.
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @category test
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace contenttype_testable;
|
||||
|
||||
/**
|
||||
* Testable content plugin class.
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class content extends \core_contentbank\content {
|
||||
}
|
82
contentbank/tests/fixtures/testable_contenttype.php
vendored
Normal file
82
contentbank/tests/fixtures/testable_contenttype.php
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Testable contenttype plugin class.
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @category test
|
||||
* @copyright 2020 Sara Arjona <sara@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace contenttype_testable;
|
||||
|
||||
/**
|
||||
* Testable contenttype plugin class.
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @copyright 2020 Sara Arjona <sara@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class contenttype extends \core_contentbank\contenttype {
|
||||
|
||||
/** Feature for testing */
|
||||
const CAN_TEST = 'test';
|
||||
|
||||
/**
|
||||
* Returns the URL where the content will be visualized.
|
||||
*
|
||||
* @param stdClass $record Th content to be displayed.
|
||||
* @return string URL where to visualize the given content.
|
||||
*/
|
||||
public function get_view_url(\stdClass $record): string {
|
||||
$fileurl = $this->get_file_url($record->id);
|
||||
$url = $fileurl."?forcedownload=1";
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML code to render the icon for content bank contents.
|
||||
*
|
||||
* @param string $contentname The contentname to add as alt value to the icon.
|
||||
* @return string HTML code to render the icon
|
||||
*/
|
||||
public function get_icon(string $contentname): string {
|
||||
global $OUTPUT;
|
||||
|
||||
return $OUTPUT->pix_icon('f/archive-64', $contentname, 'moodle', ['class' => 'iconsize-big']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of implemented features by this plugin.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_implemented_features(): array {
|
||||
return [self::CAN_TEST];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of extensions this plugin could manage.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_manageable_extensions(): array {
|
||||
return ['.txt', '.png', '.h5p'];
|
||||
}
|
||||
}
|
104
contentbank/upload.php
Normal file
104
contentbank/upload.php
Normal file
@ -0,0 +1,104 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Upload a file to content bank.
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require('../config.php');
|
||||
require_once("$CFG->dirroot/contentbank/files_form.php");
|
||||
|
||||
require_login();
|
||||
|
||||
$contextid = optional_param('contextid', \context_system::instance()->id, PARAM_INT);
|
||||
$context = context::instance_by_id($contextid, MUST_EXIST);
|
||||
|
||||
require_capability('moodle/contentbank:upload', $context);
|
||||
|
||||
$title = get_string('contentbank');
|
||||
\core_contentbank\helper::get_page_ready($context, $title, true);
|
||||
if ($PAGE->course) {
|
||||
require_login($PAGE->course->id);
|
||||
}
|
||||
$returnurl = new \moodle_url('/contentbank/index.php', ['contextid' => $contextid]);
|
||||
|
||||
$PAGE->set_url('/contentbank/upload.php');
|
||||
$PAGE->set_context($context);
|
||||
$PAGE->navbar->add(get_string('upload', 'contentbank'));
|
||||
$PAGE->set_title($title);
|
||||
$PAGE->set_heading($title);
|
||||
$PAGE->set_pagetype('contenbank');
|
||||
|
||||
$maxbytes = $CFG->userquota;
|
||||
$maxareabytes = $CFG->userquota;
|
||||
if (has_capability('moodle/user:ignoreuserquota', $context)) {
|
||||
$maxbytes = USER_CAN_IGNORE_FILE_SIZE_LIMITS;
|
||||
$maxareabytes = FILE_AREA_MAX_BYTES_UNLIMITED;
|
||||
}
|
||||
|
||||
$cb = new \core_contentbank\contentbank();
|
||||
$accepted = $cb->get_supported_extensions_as_string($context);
|
||||
|
||||
$data = new stdClass();
|
||||
$options = array(
|
||||
'subdirs' => 1,
|
||||
'maxbytes' => $maxbytes,
|
||||
'maxfiles' => -1,
|
||||
'accepted_types' => $accepted,
|
||||
'areamaxbytes' => $maxareabytes
|
||||
);
|
||||
file_prepare_standard_filemanager($data, 'files', $options, $context, 'contentbank', 'public', 0);
|
||||
|
||||
$mform = new contentbank_files_form(null, ['contextid' => $contextid, 'data' => $data, 'options' => $options]);
|
||||
|
||||
if ($mform->is_cancelled()) {
|
||||
redirect($returnurl);
|
||||
} else if ($formdata = $mform->get_data()) {
|
||||
require_sesskey();
|
||||
|
||||
// Get the file and the contenttype to manage given file's extension.
|
||||
$usercontext = context_user::instance($USER->id);
|
||||
$fs = get_file_storage();
|
||||
$files = $fs->get_area_files($usercontext->id, 'user', 'draft', $formdata->file, 'itemid, filepath, filename', false);
|
||||
|
||||
if (!empty($files)) {
|
||||
$file = reset($files);
|
||||
$filename = $file->get_filename();
|
||||
$extension = $cb->get_extension($filename);
|
||||
$plugin = $cb->get_extension_supporter($extension, $context);
|
||||
$classname = '\\contenttype_'.$plugin.'\\contenttype';
|
||||
$record = new stdClass();
|
||||
$record->name = $filename;
|
||||
if (class_exists($classname)) {
|
||||
$contentype = new $classname($context);
|
||||
$content = $contentype->create_content($record);
|
||||
file_save_draft_area_files($formdata->file, $contextid, 'contentbank', 'public', $content->get_id());
|
||||
}
|
||||
}
|
||||
redirect($returnurl);
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->box_start('generalbox');
|
||||
|
||||
$mform->display();
|
||||
|
||||
echo $OUTPUT->box_end();
|
||||
echo $OUTPUT->footer();
|
67
contentbank/view.php
Normal file
67
contentbank/view.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Generic content bank visualizer.
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require('../config.php');
|
||||
|
||||
require_login();
|
||||
|
||||
$id = required_param('id', PARAM_INT);
|
||||
$record = $DB->get_record('contentbank_content', ['id' => $id], '*', MUST_EXIST);
|
||||
$context = context::instance_by_id($record->contextid, MUST_EXIST);
|
||||
require_capability('moodle/contentbank:access', $context);
|
||||
|
||||
$returnurl = new \moodle_url('/contentbank/index.php');
|
||||
$plugin = core_plugin_manager::instance()->get_plugin_info($record->contenttype);
|
||||
if (!$plugin || !$plugin->is_enabled()) {
|
||||
print_error('unsupported', 'core_contentbank', $returnurl);
|
||||
}
|
||||
|
||||
$title = get_string('contentbank');
|
||||
\core_contentbank\helper::get_page_ready($context, $title, true);
|
||||
if ($PAGE->course) {
|
||||
require_login($PAGE->course->id);
|
||||
}
|
||||
$returnurl = new \moodle_url('/contentbank/index.php', ['contextid' => $context->id]);
|
||||
|
||||
$PAGE->set_url(new \moodle_url('/contentbank/view.php', ['id' => $id]));
|
||||
$PAGE->set_context($context);
|
||||
$PAGE->navbar->add($record->name);
|
||||
$PAGE->set_heading($title);
|
||||
$title .= ": ".$record->name;
|
||||
$PAGE->set_title($title);
|
||||
$PAGE->set_pagetype('contenbank');
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->box_start('generalbox');
|
||||
|
||||
$managerlass = "\\$record->contenttype\\contenttype";
|
||||
if (class_exists($managerlass)) {
|
||||
$manager = new $managerlass($context);
|
||||
if ($manager->can_access()) {
|
||||
echo $manager->get_view_content($record);
|
||||
}
|
||||
}
|
||||
|
||||
echo $OUTPUT->box_end();
|
||||
echo $OUTPUT->footer();
|
@ -399,6 +399,7 @@ $string['contextlockappliestoadmin'] = 'Context freezing applies to administrato
|
||||
$string['contextlockappliestoadmin_desc'] = 'If disabled, administrators remain with write access to any frozen contexts.';
|
||||
$string['cookiehttponly'] = 'Only http cookies';
|
||||
$string['cookiesecure'] = 'Secure cookies only';
|
||||
$string['contenttypeuninstalling'] = 'There are {$a->count} contents supported by {$a->type}. They will be deleted. Are you sure you want to proceed?';
|
||||
$string['country'] = 'Default country';
|
||||
$string['course_customfield'] = 'Course custom fields';
|
||||
$string['coursecolor'] = 'Colour {$a}';
|
||||
|
@ -41,6 +41,8 @@ $string['cachedef_calendar_subscriptions'] = 'Calendar subscriptions';
|
||||
$string['cachedef_calendar_categories'] = 'Calendar course categories that a user can access';
|
||||
$string['cachedef_capabilities'] = 'System capabilities list';
|
||||
$string['cachedef_config'] = 'Config settings';
|
||||
$string['cachedef_contentbank_enabled_extensions'] = 'Allowed extensions and its supporter plugins in content bank';
|
||||
$string['cachedef_contentbank_context_extensions'] = 'Allowed extensions and its supporter plugins in a content bank context';
|
||||
$string['cachedef_coursecat'] = 'Course categories lists for particular user';
|
||||
$string['cachedef_coursecatrecords'] = 'Course categories records';
|
||||
$string['cachedef_coursecattree'] = 'Course categories tree';
|
||||
|
34
lang/en/contentbank.php
Normal file
34
lang/en/contentbank.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Strings for component 'contentbank', language 'en'
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['author'] = 'Author';
|
||||
$string['file'] = 'Upload content';
|
||||
$string['file_help'] = 'Files may be stored in the content bank for use in courses. Only files used by content types enabled on the site may be uploaded.';
|
||||
$string['name'] = 'Content';
|
||||
$string['privacy:metadata:userid'] = 'The ID of the user creating or modifying content bank content.';
|
||||
$string['privacy:metadata:content:usercreated'] = 'The user has created the content.';
|
||||
$string['privacy:metadata:content:usermodified'] = 'Last user has modified the content.';
|
||||
$string['timecreated'] = 'Time created';
|
||||
$string['unsupported'] = 'This content type is not supported';
|
||||
$string['upload'] = 'Upload';
|
@ -181,6 +181,7 @@ $string['commentmisconf'] = 'Comment ID is misconfigured';
|
||||
$string['componentisuptodate'] = 'Component is up-to-date';
|
||||
$string['confirmationnotenabled'] = 'User confirmation is not enabled on this site';
|
||||
$string['confirmsesskeybad'] = 'Sorry, but your session key could not be confirmed to carry out this action. This security feature prevents against accidental or malicious execution of important functions in your name. Please make sure you really wanted to execute this function.';
|
||||
$string['contenttypenotfound'] = 'The \'{$a}\' content bank type doesn\'t exist or is not recognized';
|
||||
$string['couldnotassignrole'] = 'A serious but unspecified error occurred while trying to assign a role to you';
|
||||
$string['couldnotupdatenoexistinguser'] = 'Cannot update the user - user doesn\'t exist';
|
||||
$string['couldnotverifyagedigitalconsent'] = 'An error occurred while trying to verify the age of digital consent.<br />Please contact administrator.';
|
||||
@ -312,6 +313,7 @@ $string['invalidcommentarea'] = 'Invalid comment area';
|
||||
$string['invalidcommentparam'] = 'Invalid comment parameters';
|
||||
$string['invalidcomponent'] = 'Invalid component name';
|
||||
$string['invalidconfirmdata'] = 'Invalid confirmation data';
|
||||
$string['invalidcontentid'] = 'Invalid content ID';
|
||||
$string['invalidcontext'] = 'Invalid context';
|
||||
$string['invalidcourse'] = 'Invalid course';
|
||||
$string['invalidcourseid'] = 'You are trying to use an invalid course ID';
|
||||
|
@ -274,6 +274,7 @@ $string['confirmcheckfull'] = 'Are you absolutely sure you want to confirm {$a}
|
||||
$string['confirmcoursemove'] = 'Are you sure you want to move this course ({$a->course}) into this category ({$a->category})?';
|
||||
$string['considereddigitalminor'] = 'You are too young to create an account on this site.';
|
||||
$string['content'] = 'Content';
|
||||
$string['contentbank'] = 'Content bank';
|
||||
$string['continue'] = 'Continue';
|
||||
$string['continuetocourse'] = 'Click here to enter your course';
|
||||
$string['convertingwikitomarkdown'] = 'Converting wiki to Markdown';
|
||||
@ -1182,6 +1183,7 @@ $string['makethismyhome'] = 'Make this my home page';
|
||||
$string['makeunavailable'] = 'Make unavailable';
|
||||
$string['manageblocks'] = 'Blocks';
|
||||
$string['managecategorythis'] = 'Manage this category';
|
||||
$string['managecontentbanktypes'] = 'Manage content bank content types';
|
||||
$string['managecourses'] = 'Manage courses';
|
||||
$string['managedataformats'] = 'Manage data formats';
|
||||
$string['managedatabase'] = 'Database';
|
||||
|
@ -124,6 +124,8 @@ $string['type_cachestore'] = 'Cache store';
|
||||
$string['type_cachestore_plural'] = 'Cache stores';
|
||||
$string['type_calendartype'] = 'Calendar type';
|
||||
$string['type_calendartype_plural'] = 'Calendar types';
|
||||
$string['type_contentbank'] = 'Content bank';
|
||||
$string['type_contentbank_plural'] = 'Content bank plugins';
|
||||
$string['type_customfield'] = 'Custom field';
|
||||
$string['type_customfield_plural'] = 'Custom fields';
|
||||
$string['type_coursereport'] = 'Course report';
|
||||
|
@ -150,6 +150,8 @@ $string['confirmunassign'] = 'Are you sure you wish to remove this role from thi
|
||||
$string['confirmunassigntitle'] = 'Confirm role change';
|
||||
$string['confirmunassignyes'] = 'Remove';
|
||||
$string['confirmunassignno'] = 'Cancel';
|
||||
$string['contentbank:access'] = 'Access the content bank';
|
||||
$string['contentbank:upload'] = 'Upload new content in the content bank';
|
||||
$string['context'] = 'Context';
|
||||
$string['course:activityvisibility'] = 'Hide/show activities';
|
||||
$string['course:bulkmessaging'] = 'Send a message to many people';
|
||||
|
147
lib/adminlib.php
147
lib/adminlib.php
@ -8257,6 +8257,153 @@ class admin_setting_managemediaplayers extends admin_setting {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Content bank content types manager. Allow reorder and to enable/disable content bank content types and jump to settings
|
||||
*
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class admin_setting_managecontentbankcontenttypes extends admin_setting {
|
||||
|
||||
/**
|
||||
* Calls parent::__construct with specific arguments
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->nosave = true;
|
||||
parent::__construct('contentbank', new lang_string('managecontentbanktypes'), '', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns true
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public function get_setting() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns true
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public function get_defaultsetting() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns '' and doesn't write anything
|
||||
*
|
||||
* @param mixed $data string or array, must not be NULL
|
||||
* @return string Always returns ''
|
||||
*/
|
||||
public function write_setting($data) {
|
||||
// Do not write any setting.
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Search to find if Query is related to content bank plugin
|
||||
*
|
||||
* @param string $query The string to search for
|
||||
* @return bool true for related false for not
|
||||
*/
|
||||
public function is_related($query) {
|
||||
if (parent::is_related($query)) {
|
||||
return true;
|
||||
}
|
||||
$types = core_plugin_manager::instance()->get_plugins_of_type('contenttype');
|
||||
foreach ($types as $type) {
|
||||
if (strpos($type->component, $query) !== false ||
|
||||
strpos(core_text::strtolower($type->displayname), $query) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return XHTML to display control
|
||||
*
|
||||
* @param mixed $data Unused
|
||||
* @param string $query
|
||||
* @return string highlight
|
||||
*/
|
||||
public function output_html($data, $query='') {
|
||||
global $CFG, $OUTPUT;
|
||||
$return = '';
|
||||
|
||||
$types = core_plugin_manager::instance()->get_plugins_of_type('contenttype');
|
||||
$txt = get_strings(array('settings', 'name', 'enable', 'disable', 'order', 'up', 'down', 'default'));
|
||||
$txt->uninstall = get_string('uninstallplugin', 'core_admin');
|
||||
|
||||
$table = new html_table();
|
||||
$table->head = array($txt->name, $txt->enable, $txt->order, $txt->settings, $txt->uninstall);
|
||||
$table->align = array('left', 'center', 'center', 'center', 'center');
|
||||
$table->attributes['class'] = 'managecontentbanktable generaltable admintable';
|
||||
$table->data = array();
|
||||
$spacer = $OUTPUT->pix_icon('spacer', '', 'moodle', array('class' => 'iconsmall'));
|
||||
|
||||
$totalenabled = 0;
|
||||
$count = 0;
|
||||
foreach ($types as $type) {
|
||||
if ($type->is_enabled() && $type->is_installed_and_upgraded()) {
|
||||
$totalenabled++;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($types as $type) {
|
||||
$url = new moodle_url('/admin/contentbank.php',
|
||||
array('sesskey' => sesskey(), 'name' => $type->name));
|
||||
|
||||
$class = '';
|
||||
$strtypename = $type->displayname;
|
||||
if ($type->is_enabled()) {
|
||||
$hideshow = html_writer::link($url->out(false, array('action' => 'disable')),
|
||||
$OUTPUT->pix_icon('t/hide', $txt->disable, 'moodle', array('class' => 'iconsmall')));
|
||||
} else {
|
||||
$class = 'dimmed_text';
|
||||
$hideshow = html_writer::link($url->out(false, array('action' => 'enable')),
|
||||
$OUTPUT->pix_icon('t/show', $txt->enable, 'moodle', array('class' => 'iconsmall')));
|
||||
}
|
||||
|
||||
$updown = '';
|
||||
if ($count) {
|
||||
$updown .= html_writer::link($url->out(false, array('action' => 'up')),
|
||||
$OUTPUT->pix_icon('t/up', $txt->up, 'moodle', array('class' => 'iconsmall'))). '';
|
||||
} else {
|
||||
$updown .= $spacer;
|
||||
}
|
||||
if ($count < count($types) - 1) {
|
||||
$updown .= ' '.html_writer::link($url->out(false, array('action' => 'down')),
|
||||
$OUTPUT->pix_icon('t/down', $txt->down, 'moodle', array('class' => 'iconsmall')));
|
||||
} else {
|
||||
$updown .= $spacer;
|
||||
}
|
||||
|
||||
$settings = '';
|
||||
if ($type->get_settings_url()) {
|
||||
$settings = html_writer::link($type->get_settings_url(), $txt->settings);
|
||||
}
|
||||
|
||||
$uninstall = '';
|
||||
if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url('contenttype_'.$type->name, 'manage')) {
|
||||
$uninstall = html_writer::link($uninstallurl, $txt->uninstall);
|
||||
}
|
||||
|
||||
$row = new html_table_row(array($strtypename, $hideshow, $updown, $settings, $uninstall));
|
||||
if ($class) {
|
||||
$row->attributes['class'] = $class;
|
||||
}
|
||||
$table->data[] = $row;
|
||||
$count++;
|
||||
}
|
||||
$return .= html_writer::table($table);
|
||||
return highlight($query, $return);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise admin page - this function does require login and permission
|
||||
* checks specified in page definition.
|
||||
|
@ -208,6 +208,7 @@ class icon_system_fontawesome extends icon_system_font {
|
||||
'core:i/cohort' => 'fa-users',
|
||||
'core:i/competencies' => 'fa-check-square-o',
|
||||
'core:i/completion_self' => 'fa-user-o',
|
||||
'core:i/contentbank' => 'fa-paint-brush',
|
||||
'core:i/dashboard' => 'fa-tachometer',
|
||||
'core:i/lock' => 'fa-lock',
|
||||
'core:i/categoryevent' => 'fa-cubes',
|
||||
@ -333,6 +334,7 @@ class icon_system_fontawesome extends icon_system_font {
|
||||
'core:i/unflagged' => 'fa-flag-o',
|
||||
'core:i/unlock' => 'fa-unlock',
|
||||
'core:i/up' => 'fa-arrow-up',
|
||||
'core:i/upload' => 'fa-upload',
|
||||
'core:i/userevent' => 'fa-user',
|
||||
'core:i/user' => 'fa-user',
|
||||
'core:i/users' => 'fa-users',
|
||||
|
@ -1816,6 +1816,10 @@ class core_plugin_manager {
|
||||
'gregorian'
|
||||
),
|
||||
|
||||
'contenttype' => array(
|
||||
'h5p'
|
||||
),
|
||||
|
||||
'customfield' => array(
|
||||
'checkbox', 'date', 'select', 'text', 'textarea'
|
||||
),
|
||||
|
199
lib/classes/plugininfo/contenttype.php
Normal file
199
lib/classes/plugininfo/contenttype.php
Normal file
@ -0,0 +1,199 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Defines classes used for plugin info.
|
||||
*
|
||||
* @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\plugininfo;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Class for contentbank plugins
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class contenttype extends base {
|
||||
|
||||
|
||||
/**
|
||||
* Defines if there should be a way to uninstall the plugin via the administration UI.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_uninstall_allowed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name for the settings section.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_settings_section_name() {
|
||||
return 'contentbanksetting' . $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the global settings for a particular contentbank plugin (if there are any)
|
||||
*
|
||||
* @param \part_of_admin_tree $adminroot
|
||||
* @param string $parentnodename
|
||||
* @param bool $hassiteconfig
|
||||
*/
|
||||
public function load_settings(\part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) {
|
||||
global $CFG, $USER, $DB, $OUTPUT, $PAGE; // In case settings.php wants to refer to them.
|
||||
$ADMIN = $adminroot; // May be used in settings.php.
|
||||
$plugininfo = $this; // Also can be used inside settings.php
|
||||
$contenttype = $this; // Also to be used inside settings.php.
|
||||
|
||||
if (!$this->is_installed_and_upgraded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$hassiteconfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
$section = $this->get_settings_section_name();
|
||||
|
||||
$settings = null;
|
||||
if (file_exists($this->full_path('settings.php'))) {
|
||||
$settings = new \admin_settingpage($section, $this->displayname, 'moodle/site:config', $this->is_enabled() === false);
|
||||
include($this->full_path('settings.php')); // This may also set $settings to null.
|
||||
}
|
||||
if ($settings) {
|
||||
$ADMIN->add($parentnodename, $settings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return URL used for management of plugins of this type.
|
||||
* @return \moodle_url
|
||||
*/
|
||||
public static function get_manage_url() {
|
||||
return new \moodle_url('/admin/settings.php', array('section' => 'managecontentbanktypes'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gathers and returns the information about all plugins of the given type
|
||||
*
|
||||
* @param string $type the name of the plugintype, eg. mod, auth or workshopform
|
||||
* @param string $typerootdir full path to the location of the plugin dir
|
||||
* @param string $typeclass the name of the actually called class
|
||||
* @param core_plugin_manager $pluginman the plugin manager calling this method
|
||||
* @return array of plugintype classes, indexed by the plugin name
|
||||
*/
|
||||
public static function get_plugins($type, $typerootdir, $typeclass, $pluginman) {
|
||||
global $CFG;
|
||||
|
||||
$contents = parent::get_plugins($type, $typerootdir, $typeclass, $pluginman);
|
||||
if (!empty($CFG->contentbank_plugins_sortorder)) {
|
||||
$order = explode(',', $CFG->contentbank_plugins_sortorder);
|
||||
$order = array_merge(array_intersect($order, array_keys($contents)),
|
||||
array_diff(array_keys($contents), $order));
|
||||
} else {
|
||||
$order = array_keys($contents);
|
||||
}
|
||||
$sortedcontents = array();
|
||||
foreach ($order as $contentname) {
|
||||
$sortedcontents[$contentname] = $contents[$contentname];
|
||||
}
|
||||
return $sortedcontents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all enabled plugins, the result may include missing plugins.
|
||||
* @return array|null of enabled plugins $pluginname=>$pluginname, null means unknown
|
||||
*/
|
||||
public static function get_enabled_plugins() {
|
||||
global $CFG;
|
||||
|
||||
$plugins = \core_plugin_manager::instance()->get_installed_plugins('contenttype');
|
||||
|
||||
if (!$plugins) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$plugins = array_keys($plugins);
|
||||
// Order the plugins.
|
||||
if (!empty($CFG->contentbank_plugins_sortorder)) {
|
||||
$order = explode(',', $CFG->contentbank_plugins_sortorder);
|
||||
$order = array_merge(array_intersect($order, $plugins),
|
||||
array_diff($plugins, $order));
|
||||
} else {
|
||||
$order = $plugins;
|
||||
}
|
||||
|
||||
// Filter to return only enabled plugins.
|
||||
$enabled = array();
|
||||
foreach ($order as $plugin) {
|
||||
$disabled = get_config('contentbank_' . $plugin, 'disabled');
|
||||
if (empty($disabled)) {
|
||||
$enabled[$plugin] = $plugin;
|
||||
}
|
||||
}
|
||||
return $enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional extra warning before uninstallation adding number of existing contenttype contents.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_uninstall_extra_warning() {
|
||||
global $DB;
|
||||
|
||||
$contentcount = $DB->count_records('contentbank_content', ['contenttype' => "contenttype_$this->name"]);
|
||||
if (!$contentcount) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$message = get_string('contenttypeuninstalling',
|
||||
'core_admin',
|
||||
(object)['count' => $contentcount, 'type' => $this->displayname]
|
||||
);
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-uninstall hook.
|
||||
*
|
||||
* This is intended for disabling of plugin, some DB table purging, etc.
|
||||
*
|
||||
* NOTE: to be called from uninstall_plugin() only.
|
||||
*/
|
||||
public function uninstall_cleanup() {
|
||||
global $DB;
|
||||
|
||||
$contents = $DB->get_records('contentbank_content', ['contenttype' => 'contenttype_'.$this->name]);
|
||||
foreach ($contents as $content) {
|
||||
$fs = get_file_storage();
|
||||
$fs->delete_area_files($content->contextid, 'contentbank', false, $content->id);
|
||||
}
|
||||
$DB->delete_records('contentbank_content', ['contenttype' => 'contenttype_'.$this->name]);
|
||||
|
||||
parent::uninstall_cleanup();
|
||||
}
|
||||
}
|
@ -35,6 +35,7 @@
|
||||
"cachestore": "cache\/stores",
|
||||
"cachelock": "cache\/locks",
|
||||
"fileconverter": "files\/converter",
|
||||
"contenttype": "contentbank\/contenttype",
|
||||
"theme": "theme",
|
||||
"local": "local",
|
||||
"h5plib": "h5p\/h5plib"
|
||||
@ -57,6 +58,7 @@
|
||||
"comment": "comment",
|
||||
"competency": "competency",
|
||||
"completion": "completion",
|
||||
"contentbank": "contentbank",
|
||||
"countries": null,
|
||||
"course": "course",
|
||||
"currencies": null,
|
||||
|
@ -2479,5 +2479,27 @@ $capabilities = array(
|
||||
'archetypes' => [
|
||||
'manager' => CAP_ALLOW,
|
||||
]
|
||||
]
|
||||
],
|
||||
|
||||
// Content bank capabilities.
|
||||
'moodle/contentbank:access' => array(
|
||||
'captype' => 'read',
|
||||
'contextlevel' => CONTEXT_COURSE,
|
||||
'archetypes' => array(
|
||||
'manager' => CAP_ALLOW,
|
||||
'coursecreator' => CAP_ALLOW,
|
||||
'editingteacher' => CAP_ALLOW,
|
||||
)
|
||||
),
|
||||
|
||||
'moodle/contentbank:upload' => array(
|
||||
'riskbitmask' => RISK_SPAM,
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_COURSE,
|
||||
'archetypes' => array(
|
||||
'manager' => CAP_ALLOW,
|
||||
'coursecreator' => CAP_ALLOW,
|
||||
'editingteacher' => CAP_ALLOW,
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -432,4 +432,18 @@ $definitions = array(
|
||||
'mode' => cache_store::MODE_APPLICATION,
|
||||
'simplekeys' => true,
|
||||
],
|
||||
|
||||
// Caches contentbank extensions management.
|
||||
'contentbank_enabled_extensions' => [
|
||||
'mode' => cache_store::MODE_APPLICATION,
|
||||
'simplekeys' => true,
|
||||
'simpledata' => true,
|
||||
'staticacceleration' => true,
|
||||
],
|
||||
'contentbank_context_extensions' => [
|
||||
'mode' => cache_store::MODE_REQUEST,
|
||||
'simplekeys' => true,
|
||||
'simpledata' => true,
|
||||
'staticacceleration' => true,
|
||||
],
|
||||
);
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="lib/db" VERSION="20191109" COMMENT="XMLDB file for core Moodle tables"
|
||||
<XMLDB PATH="lib/db" VERSION="20200415" COMMENT="XMLDB file for core Moodle tables"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
@ -4217,5 +4217,29 @@
|
||||
<KEY NAME="libraryid" TYPE="foreign" FIELDS="libraryid" REFTABLE="h5p_libraries" REFFIELDS="id"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
<TABLE NAME="contentbank_content" COMMENT="This table stores content data in the content bank.">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
||||
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
|
||||
<FIELD NAME="contenttype" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
|
||||
<FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="References context.id."/>
|
||||
<FIELD NAME="instanceid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
|
||||
<FIELD NAME="configdata" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
|
||||
<FIELD NAME="usercreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The original author of the content"/>
|
||||
<FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
|
||||
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
<KEY NAME="contextid" TYPE="foreign" FIELDS="contextid" REFTABLE="context" REFFIELDS="id"/>
|
||||
<KEY NAME="usermodified" TYPE="foreign" FIELDS="usermodified" REFTABLE="user" REFFIELDS="id"/>
|
||||
<KEY NAME="usercreated" TYPE="foreign" FIELDS="usercreated" REFTABLE="user" REFFIELDS="id"/>
|
||||
</KEYS>
|
||||
<INDEXES>
|
||||
<INDEX NAME="name" UNIQUE="false" FIELDS="name"/>
|
||||
<INDEX NAME="instance" UNIQUE="false" FIELDS="contextid, contenttype, instanceid"/>
|
||||
</INDEXES>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
@ -2258,5 +2258,38 @@ function xmldb_main_upgrade($oldversion) {
|
||||
upgrade_main_savepoint(true, 2020040700.00);
|
||||
}
|
||||
|
||||
if ($oldversion < 2020041500.00) {
|
||||
// Define table to store contentbank contents.
|
||||
$table = new xmldb_table('contentbank_content');
|
||||
|
||||
// Adding fields to table content_bank.
|
||||
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
|
||||
$table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('contenttype', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('instanceid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
|
||||
$table->add_field('configdata', XMLDB_TYPE_TEXT, null, null, null, null, null);
|
||||
$table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
|
||||
$table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
|
||||
$table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, null, null, '0');
|
||||
|
||||
// Adding keys to table contentbank_content.
|
||||
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
|
||||
$table->add_key('contextid', XMLDB_KEY_FOREIGN, ['contextid'], 'context', ['id']);
|
||||
$table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']);
|
||||
$table->add_key('usercreated', XMLDB_KEY_FOREIGN, ['usercreated'], 'user', ['id']);
|
||||
|
||||
// Adding indexes to table contentbank_content.
|
||||
$table->add_index('name', XMLDB_INDEX_NOTUNIQUE, ['name']);
|
||||
$table->add_index('instance', XMLDB_INDEX_NOTUNIQUE, ['contextid', 'contenttype', 'instanceid']);
|
||||
|
||||
if (!$dbman->table_exists($table)) {
|
||||
$dbman->create_table($table);
|
||||
}
|
||||
|
||||
// Main savepoint reached.
|
||||
upgrade_main_savepoint(true, 2020041500.00);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -4907,8 +4907,29 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null, $offlin
|
||||
\core\session\manager::write_close(); // Unlock session during file serving.
|
||||
send_stored_file($file, 60*60, 0, $forcedownload, $sendfileoptions);
|
||||
}
|
||||
} else if ($component === 'contentbank') {
|
||||
if ($filearea != 'public' || isguestuser()) {
|
||||
send_file_not_found();
|
||||
}
|
||||
|
||||
// ========================================================================================================================
|
||||
if ($context->contextlevel == CONTEXT_SYSTEM || $context->contextlevel == CONTEXT_COURSECAT) {
|
||||
require_login();
|
||||
} else if ($context->contextlevel == CONTEXT_COURSE) {
|
||||
require_login($course);
|
||||
} else {
|
||||
send_file_not_found();
|
||||
}
|
||||
|
||||
$itemid = (int)array_shift($args);
|
||||
$filename = array_pop($args);
|
||||
$filepath = $args ? '/'.implode('/', $args).'/' : '/';
|
||||
if (!$file = $fs->get_file($context->id, $component, $filearea, $itemid, $filepath, $filename) or
|
||||
$file->is_directory()) {
|
||||
send_file_not_found();
|
||||
}
|
||||
|
||||
\core\session\manager::write_close(); // Unlock session during file serving.
|
||||
send_stored_file($file, 0, 0, true, $sendfileoptions); // must force download - security!
|
||||
} else if (strpos($component, 'mod_') === 0) {
|
||||
$modname = substr($component, 4);
|
||||
if (!file_exists("$CFG->dirroot/mod/$modname/lib.php")) {
|
||||
|
@ -2914,6 +2914,31 @@ class global_navigation extends navigation_node {
|
||||
}
|
||||
}
|
||||
|
||||
if (isloggedin()) {
|
||||
$context = $this->page->context;
|
||||
switch ($context->contextlevel) {
|
||||
case CONTEXT_COURSECAT:
|
||||
$type = self::TYPE_CATEGORY;
|
||||
break;
|
||||
case CONTEXT_COURSE:
|
||||
$type = self::TYPE_COURSE;
|
||||
if ($COURSE->id != $SITE->id) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
$type = self::TYPE_CUSTOM;
|
||||
$context = $sitecontext;
|
||||
}
|
||||
|
||||
$params = ['contextid' => $context->id];
|
||||
if (has_capability('moodle/contentbank:access', $context)) {
|
||||
$url = new moodle_url('/contentbank/index.php', $params);
|
||||
$node = $coursenode->add(get_string('contentbank'), $url,
|
||||
$type, null, 'contentbank', new pix_icon('i/contentbank', ''));
|
||||
$node->showinflatnavigation = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ class core_component_testcase extends advanced_testcase {
|
||||
* this is defined here to annoy devs that try to add more without any thinking,
|
||||
* always verify that it does not collide with any existing add-on modules and subplugins!!!
|
||||
*/
|
||||
const SUBSYSTEMCOUNT = 70;
|
||||
const SUBSYSTEMCOUNT = 71;
|
||||
|
||||
public function setUp() {
|
||||
$psr0namespaces = new ReflectionProperty('core_component', 'psr0namespaces');
|
||||
|
@ -197,6 +197,9 @@
|
||||
<testsuite name="core_xapi_testsuite">
|
||||
<directory suffix="_test.php">lib/xapi/tests</directory>
|
||||
</testsuite>
|
||||
<testsuite name="core_contentbank_testsuite">
|
||||
<directory suffix="_test.php">contentbank/tests</directory>
|
||||
</testsuite>
|
||||
|
||||
<!--Plugin suites: use admin/tool/phpunit/cli/util.php to build phpunit.xml from phpunit.xml.dist with up-to-date list of plugins in current install-->
|
||||
<!--@plugin_suites_start@-->
|
||||
|
BIN
pix/i/upload.png
Normal file
BIN
pix/i/upload.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 199 B |
3
pix/i/upload.svg
Normal file
3
pix/i/upload.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
|
||||
]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 -0.4 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M16 8.6v6c0 .5-.5 1-1 1H1c-.5 0-1-.5-1-1v-6c0-.5.5-1 1-1h1c.5 0 1 .5 1 1v4h10v-4c0-.5.5-1 1-1h1c.5 0 1 .4 1 1zM12.4 4L8.7.3C8.6.1 8.3 0 8 0c-.2 0-.5.1-.7.3L3.6 4c-.4.4-.4 1 0 1.4l.7.7c.4.4 1 .4 1.4 0l.8-.8v4.2c0 .5.5 1.1 1 1.1h1c.6 0 1-.5 1-1.1V5.3l.8.8c.4.4 1 .4 1.4 0l.7-.7c.4-.4.4-1 0-1.4z" fill="#999"/></svg>
|
After Width: | Height: | Size: 620 B |
@ -14,6 +14,7 @@ $breadcrumb-divider-rtl: "◀" !default;
|
||||
@import "moodle/blocks";
|
||||
@import "moodle/bootswatch";
|
||||
@import "moodle/calendar";
|
||||
@import "moodle/contentbank";
|
||||
@import "moodle/course";
|
||||
@import "moodle/drawer";
|
||||
@import "moodle/dashboard";
|
||||
|
64
theme/boost/scss/moodle/contentbank.scss
Normal file
64
theme/boost/scss/moodle/contentbank.scss
Normal file
@ -0,0 +1,64 @@
|
||||
/* Use a variable for the drawer background colors. */
|
||||
$navbar-bg: darken($body-bg, 5%) !default;
|
||||
|
||||
// Content bank
|
||||
.content-bank-container {
|
||||
min-height: 140px;
|
||||
padding-bottom: 15px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.cb-navbar {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
background-color: $navbar-bg;
|
||||
min-height: 40px;
|
||||
padding: 10px;
|
||||
}
|
||||
// Icon view (Content bank)
|
||||
.cb-iconview .cb-file {
|
||||
float: left;
|
||||
margin: 10px 10px 35px;
|
||||
}
|
||||
.cb-iconview .cb-thumbnail {
|
||||
min-width: 110px;
|
||||
min-height: 110px;
|
||||
line-height: 110px;
|
||||
border: 1px solid #fff;
|
||||
.icon {
|
||||
margin: 0;
|
||||
}
|
||||
img {
|
||||
padding: 3px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
.cb-iconview .cb-thumbnail:hover {
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
@include box-shadow(inset 0 0 10px0 #ccc);
|
||||
}
|
||||
.cb-iconview .cb-contentname-field {
|
||||
height: 33px;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
.cb-contentname {
|
||||
background: #fff;
|
||||
padding: 5px 10px 12px;
|
||||
min-width: 112px;
|
||||
}
|
||||
}
|
||||
.cb-iconview .cb-file:focus,
|
||||
.cb-iconview .cb-file:hover {
|
||||
// Undo truncating of text on hover.
|
||||
.cb-contentname-field {
|
||||
overflow: visible;
|
||||
z-index: 1000;
|
||||
}
|
||||
.cb-contentname {
|
||||
overflow: inherit;
|
||||
white-space: normal;
|
||||
text-overflow: inherit;
|
||||
}
|
||||
}
|
||||
.content-bank-toolbar .cb-tool .icon {
|
||||
margin: 0.5em;
|
||||
}
|
@ -98,7 +98,8 @@ body {
|
||||
}
|
||||
|
||||
.filemanager-container,
|
||||
.filepicker-filelist {
|
||||
.filepicker-filelist,
|
||||
.content-bank-container {
|
||||
@extend .border;
|
||||
}
|
||||
|
||||
|
@ -6747,7 +6747,8 @@ button.bg-dark:focus {
|
||||
background-color: transparent !important; }
|
||||
|
||||
.border, .filemanager-container,
|
||||
.filepicker-filelist {
|
||||
.filepicker-filelist,
|
||||
.content-bank-container {
|
||||
border: 1px solid #dee2e6 !important; }
|
||||
|
||||
.border-top {
|
||||
@ -12538,6 +12539,60 @@ table.calendartable caption {
|
||||
.cal_courses_flt {
|
||||
color: #868e96; }
|
||||
|
||||
/* Use a variable for the drawer background colors. */
|
||||
.content-bank-container {
|
||||
min-height: 140px;
|
||||
padding-bottom: 15px;
|
||||
overflow: hidden; }
|
||||
|
||||
.cb-navbar {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
background-color: #f2f2f2;
|
||||
min-height: 40px;
|
||||
padding: 10px; }
|
||||
|
||||
.cb-iconview .cb-file {
|
||||
float: left;
|
||||
margin: 10px 10px 35px; }
|
||||
|
||||
.cb-iconview .cb-thumbnail {
|
||||
min-width: 110px;
|
||||
min-height: 110px;
|
||||
line-height: 110px;
|
||||
border: 1px solid #fff; }
|
||||
.cb-iconview .cb-thumbnail .icon {
|
||||
margin: 0; }
|
||||
.cb-iconview .cb-thumbnail img {
|
||||
padding: 3px;
|
||||
vertical-align: middle; }
|
||||
|
||||
.cb-iconview .cb-thumbnail:hover {
|
||||
background: #fff;
|
||||
border: 1px solid #ddd; }
|
||||
|
||||
.cb-iconview .cb-contentname-field {
|
||||
height: 33px;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden; }
|
||||
.cb-iconview .cb-contentname-field .cb-contentname {
|
||||
background: #fff;
|
||||
padding: 5px 10px 12px;
|
||||
min-width: 112px; }
|
||||
|
||||
.cb-iconview .cb-file:focus .cb-contentname-field,
|
||||
.cb-iconview .cb-file:hover .cb-contentname-field {
|
||||
overflow: visible;
|
||||
z-index: 1000; }
|
||||
|
||||
.cb-iconview .cb-file:focus .cb-contentname,
|
||||
.cb-iconview .cb-file:hover .cb-contentname {
|
||||
overflow: inherit;
|
||||
white-space: normal;
|
||||
text-overflow: inherit; }
|
||||
|
||||
.content-bank-toolbar .cb-tool .icon {
|
||||
margin: 0.5em; }
|
||||
|
||||
/* course.less */
|
||||
/* COURSE CONTENT */
|
||||
.section_add_menus {
|
||||
|
@ -12750,6 +12750,60 @@ table.calendartable caption {
|
||||
.cal_courses_flt {
|
||||
color: #868e96; }
|
||||
|
||||
/* Use a variable for the drawer background colors. */
|
||||
.content-bank-container {
|
||||
min-height: 140px;
|
||||
padding-bottom: 15px;
|
||||
overflow: hidden; }
|
||||
|
||||
.cb-navbar {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
background-color: #f2f2f2;
|
||||
min-height: 40px;
|
||||
padding: 10px; }
|
||||
|
||||
.cb-iconview .cb-file {
|
||||
float: left;
|
||||
margin: 10px 10px 35px; }
|
||||
|
||||
.cb-iconview .cb-thumbnail {
|
||||
min-width: 110px;
|
||||
min-height: 110px;
|
||||
line-height: 110px;
|
||||
border: 1px solid #fff; }
|
||||
.cb-iconview .cb-thumbnail .icon {
|
||||
margin: 0; }
|
||||
.cb-iconview .cb-thumbnail img {
|
||||
padding: 3px;
|
||||
vertical-align: middle; }
|
||||
|
||||
.cb-iconview .cb-thumbnail:hover {
|
||||
background: #fff;
|
||||
border: 1px solid #ddd; }
|
||||
|
||||
.cb-iconview .cb-contentname-field {
|
||||
height: 33px;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden; }
|
||||
.cb-iconview .cb-contentname-field .cb-contentname {
|
||||
background: #fff;
|
||||
padding: 5px 10px 12px;
|
||||
min-width: 112px; }
|
||||
|
||||
.cb-iconview .cb-file:focus .cb-contentname-field,
|
||||
.cb-iconview .cb-file:hover .cb-contentname-field {
|
||||
overflow: visible;
|
||||
z-index: 1000; }
|
||||
|
||||
.cb-iconview .cb-file:focus .cb-contentname,
|
||||
.cb-iconview .cb-file:hover .cb-contentname {
|
||||
overflow: inherit;
|
||||
white-space: normal;
|
||||
text-overflow: inherit; }
|
||||
|
||||
.content-bank-toolbar .cb-tool .icon {
|
||||
margin: 0.5em; }
|
||||
|
||||
/* course.less */
|
||||
/* COURSE CONTENT */
|
||||
.section_add_menus {
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2020040800.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2020041500.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
$release = '3.9dev (Build: 20200408)'; // Human-friendly version name
|
||||
|
Loading…
x
Reference in New Issue
Block a user