mirror of
https://github.com/moodle/moodle.git
synced 2025-08-04 16:36:37 +02:00
MDL-67810 core_contentbank: added dropdown menu to create content
This commit is contained in:
parent
68fd8d8bdf
commit
75f58cbfa2
16 changed files with 437 additions and 14 deletions
|
@ -24,6 +24,7 @@
|
|||
|
||||
namespace core_contentbank;
|
||||
|
||||
use core_plugin_manager;
|
||||
use stored_file;
|
||||
use context;
|
||||
|
||||
|
@ -35,6 +36,8 @@ use context;
|
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class contentbank {
|
||||
/** @var array Enabled content types. */
|
||||
private $enabledcontenttypes = null;
|
||||
|
||||
/**
|
||||
* Obtains the list of core_contentbank_content objects currently active.
|
||||
|
@ -44,16 +47,20 @@ class contentbank {
|
|||
* @return string[] Array of contentbank contenttypes.
|
||||
*/
|
||||
public function get_enabled_content_types(): array {
|
||||
if (!is_null($this->enabledcontenttypes)) {
|
||||
return $this->enabledcontenttypes;
|
||||
}
|
||||
|
||||
$enabledtypes = \core\plugininfo\contenttype::get_enabled_plugins();
|
||||
$types = [];
|
||||
foreach ($enabledtypes as $name) {
|
||||
$contenttypeclassname = "\\contenttype_$name\\contenttype";
|
||||
$contentclassname = "\\contenttype_$name\\content";
|
||||
if (class_exists($contenttypeclassname) && class_exists($contentclassname)) {
|
||||
$types[] = $name;
|
||||
$types[$contenttypeclassname] = $name;
|
||||
}
|
||||
}
|
||||
return $types;
|
||||
return $this->enabledcontenttypes = $types;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -292,4 +299,37 @@ class contentbank {
|
|||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of content types that have the requested feature.
|
||||
*
|
||||
* @param string $feature Feature code e.g CAN_UPLOAD.
|
||||
* @param null|\context $context Optional context to check the permission to use the feature.
|
||||
* @param bool $enabled Whether check only the enabled content types or all of them.
|
||||
*
|
||||
* @return string[] List of content types where the user has permission to access the feature.
|
||||
*/
|
||||
public function get_contenttypes_with_capability_feature(string $feature, \context $context = null, bool $enabled = true): array {
|
||||
$contenttypes = [];
|
||||
// Check enabled content types or all of them.
|
||||
if ($enabled) {
|
||||
$contenttypestocheck = $this->get_enabled_content_types();
|
||||
} else {
|
||||
$plugins = core_plugin_manager::instance()->get_plugins_of_type('contenttype');
|
||||
foreach ($plugins as $plugin) {
|
||||
$contenttypeclassname = "\\{$plugin->type}_{$plugin->name}\\contenttype";
|
||||
$contenttypestocheck[$contenttypeclassname] = $plugin->name;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($contenttypestocheck as $classname => $name) {
|
||||
$contenttype = new $classname($context);
|
||||
// The method names that check the features permissions must follow the pattern can_feature.
|
||||
if ($contenttype->{"can_$feature"}()) {
|
||||
$contenttypes[$classname] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
return $contenttypes;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,10 @@ abstract class contenttype {
|
|||
/** Plugin implements uploading feature */
|
||||
const CAN_UPLOAD = 'upload';
|
||||
|
||||
/** @var context This contenttype's context. **/
|
||||
/** Plugin implements edition feature */
|
||||
const CAN_EDIT = 'edit';
|
||||
|
||||
/** @var \context This contenttype's context. **/
|
||||
protected $context = null;
|
||||
|
||||
/**
|
||||
|
@ -59,7 +62,7 @@ abstract class contenttype {
|
|||
/**
|
||||
* Fills content_bank table with appropiate information.
|
||||
*
|
||||
* @param stdClass $record An optional content record compatible object (default null)
|
||||
* @param \stdClass $record An optional content record compatible object (default null)
|
||||
* @return content Object with content bank information.
|
||||
*/
|
||||
public function create_content(\stdClass $record = null): ?content {
|
||||
|
@ -127,7 +130,7 @@ abstract class contenttype {
|
|||
* This method can be overwritten by the plugins if they need to change some other specific information.
|
||||
*
|
||||
* @param content $content The content to rename.
|
||||
* @param string $name The name of the content.
|
||||
* @param string $name The name of the content.
|
||||
* @return boolean true if the content has been renamed; false otherwise.
|
||||
*/
|
||||
public function rename_content(content $content, string $name): bool {
|
||||
|
@ -139,7 +142,7 @@ abstract class contenttype {
|
|||
* This method can be overwritten by the plugins if they need to change some other specific information.
|
||||
*
|
||||
* @param content $content The content to rename.
|
||||
* @param context $context The new context.
|
||||
* @param \context $context The new context.
|
||||
* @return boolean true if the content has been renamed; false otherwise.
|
||||
*/
|
||||
public function move_content(content $content, \context $context): bool {
|
||||
|
@ -325,6 +328,37 @@ abstract class contenttype {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the user has permission to use the editor.
|
||||
*
|
||||
* @return bool True if the user can edit content. False otherwise.
|
||||
*/
|
||||
final public function can_edit(): bool {
|
||||
if (!$this->is_feature_supported(self::CAN_EDIT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->can_access()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$classname = 'contenttype/'.$this->get_plugin_name();
|
||||
|
||||
$editioncap = $classname.':useeditor';
|
||||
$hascapabilities = has_all_capabilities(['moodle/contentbank:useeditor', $editioncap], $this->context);
|
||||
return $hascapabilities && $this->is_edit_allowed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns plugin allows edition.
|
||||
*
|
||||
* @return bool True if plugin allows edition. False otherwise.
|
||||
*/
|
||||
protected function is_edit_allowed(): bool {
|
||||
// Plugins can overwrite this function to add any check they need.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plugin supports the feature.
|
||||
*
|
||||
|
@ -348,4 +382,17 @@ abstract class contenttype {
|
|||
* @return array
|
||||
*/
|
||||
abstract public function get_manageable_extensions(): array;
|
||||
|
||||
/**
|
||||
* Returns the list of different types of the given content type.
|
||||
*
|
||||
* A content type can have one or more options for creating content. This method will report all of them or only the content
|
||||
* type itself if it has no other options.
|
||||
*
|
||||
* @return array An object for each type:
|
||||
* - string typename: descriptive name of the type.
|
||||
* - string typeeditorparams: params required by this content type editor.
|
||||
* - url typeicon: this type icon.
|
||||
*/
|
||||
abstract public function get_contenttype_types(): array;
|
||||
}
|
||||
|
|
|
@ -98,7 +98,56 @@ class bankcontent implements renderable, templatable {
|
|||
);
|
||||
}
|
||||
$data->contents = $contentdata;
|
||||
$data->tools = $this->toolbar;
|
||||
// The tools are displayed in the action bar on the index page.
|
||||
foreach ($this->toolbar as $tool) {
|
||||
// Customize the output of a tool, like dropdowns.
|
||||
$method = 'export_tool_'.$tool['name'];
|
||||
if (method_exists($this, $method)) {
|
||||
$this->$method($tool);
|
||||
}
|
||||
$data->tools[] = $tool;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the content type items to display to the Add dropdown.
|
||||
*
|
||||
* Each content type is represented as an object with the properties:
|
||||
* - name: the name of the content type.
|
||||
* - baseurl: the base content type editor URL.
|
||||
* - types: different types of the content type to display as dropdown items.
|
||||
*
|
||||
* @param array $tool Data for rendering the Add dropdown, including the editable content types.
|
||||
*/
|
||||
private function export_tool_add(array &$tool) {
|
||||
$editabletypes = $tool['contenttypes'];
|
||||
|
||||
$addoptions = [];
|
||||
foreach ($editabletypes as $class => $type) {
|
||||
$contentype = new $class($this->context);
|
||||
// Get the creation options of each content type.
|
||||
$types = $contentype->get_contenttype_types();
|
||||
if ($types) {
|
||||
// Add a text describing the content type as first option. This will be displayed in the drop down to
|
||||
// separate the options for the different content types.
|
||||
$contentdesc = new stdClass();
|
||||
$contentdesc->typename = get_string('description', $contentype->get_contenttype_name());
|
||||
array_unshift($types, $contentdesc);
|
||||
// Context data for the template.
|
||||
$addcontenttype = new stdClass();
|
||||
// Content type name.
|
||||
$addcontenttype->name = $type;
|
||||
// Content type editor base URL.
|
||||
$tool['link']->param('plugin', $type);
|
||||
$addcontenttype->baseurl = $tool['link']->out();
|
||||
// Different types of the content type.
|
||||
$addcontenttype->types = $types;
|
||||
$addoptions[] = $addcontenttype;
|
||||
}
|
||||
}
|
||||
|
||||
$tool['contenttypes'] = $addoptions;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,19 @@ $foldercontents = $cb->search_contents($search, $contextid, $contenttypes);
|
|||
|
||||
// Get the toolbar ready.
|
||||
$toolbar = array ();
|
||||
|
||||
// Place the Add button in the toolbar.
|
||||
if (has_capability('moodle/contentbank:useeditor', $context)) {
|
||||
// Get the content types for which the user can use an editor.
|
||||
$editabletypes = $cb->get_contenttypes_with_capability_feature(\core_contentbank\contenttype::CAN_EDIT, $context);
|
||||
if (!empty($editabletypes)) {
|
||||
// Editor base URL.
|
||||
$editbaseurl = new moodle_url('/contentbank/edit.php', ['contextid' => $contextid]);
|
||||
$toolbar[] = ['name' => get_string('add'), 'link' => $editbaseurl, 'dropdown' => true, 'contenttypes' => $editabletypes];
|
||||
}
|
||||
}
|
||||
|
||||
// Place the Upload button in the toolbar.
|
||||
if (has_capability('moodle/contentbank:upload', $context)) {
|
||||
// Don' show upload button if there's no plugin to support any file extension.
|
||||
$accepted = $cb->get_supported_extensions_as_string($context);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@template core_contentbank/list
|
||||
@template core_contentbank/bankcontent
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
|
@ -32,10 +32,36 @@
|
|||
},
|
||||
{
|
||||
"name": "resume.pdf",
|
||||
"title": "resume",
|
||||
"timemodified": 1589792039,
|
||||
"size": "699.3KB",
|
||||
"bytes": 716126,
|
||||
"type": "Archive (PDF)",
|
||||
"icon": "http://something/theme/image.php/boost/core/1584597850/f/pdf-64"
|
||||
}
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"name": "Add",
|
||||
"dropdown": true,
|
||||
"link": "http://something/contentbank/edit.php?contextid=1",
|
||||
"contenttypes": [
|
||||
{
|
||||
"name": "H5P Interactive Content",
|
||||
"baseurl": "http://something/contentbank/edit.php?contextid=1&plugin=h5p",
|
||||
"types": [
|
||||
{
|
||||
"typename": "H5P Interactive Content"
|
||||
},
|
||||
{
|
||||
"typename": "Accordion",
|
||||
"typeeditorparams": "library=Accordion-1.4",
|
||||
"typeicon": "http://something/pluginfile.php/1/core_h5p/libraries/13/H5P.Accordion-1.4/icon.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Upload",
|
||||
"link": "http://something/contentbank/contenttype/h5p/view.php?url=http://something/pluginfile.php/1/contentbank/public/accordion.h5p",
|
||||
|
|
|
@ -20,6 +20,27 @@
|
|||
Example context (json):
|
||||
{
|
||||
"tools": [
|
||||
{
|
||||
"name": "Add",
|
||||
"dropdown": true,
|
||||
"link": "http://something/contentbank/edit.php?contextid=1",
|
||||
"contenttypes": [
|
||||
{
|
||||
"name": "h5p",
|
||||
"baseurl": "http://something/contentbank/edit.php?contextid=1&plugin=h5p",
|
||||
"types": [
|
||||
{
|
||||
"typename": "H5P Interactive Content"
|
||||
},
|
||||
{
|
||||
"typename": "Accordion",
|
||||
"typeeditorparams": "library=Accordion-1.4",
|
||||
"typeicon": "http://something/pluginfile.php/1/core_h5p/libraries/13/H5P.Accordion-1.4/icon.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Upload",
|
||||
"link": "http://something/contentbank/contenttype/h5p/view.php?url=http://something/pluginfile.php/1/contentbank/public/accordion.h5p",
|
||||
|
@ -34,9 +55,14 @@
|
|||
}}
|
||||
|
||||
{{#tools}}
|
||||
<a href="{{{ link }}}" class="icon-no-margin btn btn-secondary" title="{{{ name }}}">
|
||||
{{#pix}} {{{ icon }}} {{/pix}} {{{ name }}}
|
||||
</a>
|
||||
{{#dropdown}}
|
||||
{{>core_contentbank/bankcontent/toolbar_dropdown}}
|
||||
{{/dropdown}}
|
||||
{{^dropdown}}
|
||||
<a href="{{{ link }}}" class="icon-no-margin btn btn-secondary" title="{{{ name }}}">
|
||||
{{#pix}} {{{ icon }}} {{/pix}} {{{ name }}}
|
||||
</a>
|
||||
{{/dropdown}}
|
||||
{{/tools}}
|
||||
<button class="icon-no-margin btn btn-secondary active ml-2"
|
||||
title="{{#str}} displayicons, contentbank {{/str}}"
|
||||
|
|
64
contentbank/templates/bankcontent/toolbar_dropdown.mustache
Normal file
64
contentbank/templates/bankcontent/toolbar_dropdown.mustache
Normal file
|
@ -0,0 +1,64 @@
|
|||
{{!
|
||||
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/bankcontent/toolbar_dropdown
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "Add",
|
||||
"dropdown": true,
|
||||
"link": "http://something/contentbank/edit.php?contextid=1",
|
||||
"contenttypes": [
|
||||
{
|
||||
"name": "h5p",
|
||||
"baseurl": "http://something/contentbank/edit.php?contextid=1&plugin=h5p",
|
||||
"types": [
|
||||
{
|
||||
"typename": "H5P Interactive Content"
|
||||
},
|
||||
{
|
||||
"typename": "Accordion",
|
||||
"typeeditorparams": "library=Accordion-1.4",
|
||||
"typeicon": "http://something/pluginfile.php/1/core_h5p/libraries/13/H5P.Accordion-1.4/icon.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}}
|
||||
<div class="btn-group mr-1" role="group">
|
||||
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" data-action="{{name}}-content"
|
||||
aria-haspopup="true" aria-expanded="false" {{^contenttypes}}title="{{#str}}nocontenttypes, core_contentbank{{/str}}"
|
||||
disabled{{/contenttypes}}>
|
||||
{{#name}} {{name}} {{/name}}
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-scrollable dropdown-menu-right">
|
||||
{{#contenttypes}}
|
||||
{{#types}}
|
||||
{{^typeeditorparams}}
|
||||
<h6 class="dropdown-header">{{ typename }}</h6>
|
||||
{{/typeeditorparams}}
|
||||
{{#typeeditorparams}}
|
||||
<a class="dropdown-item icon-size-4" href="{{{ baseurl }}}&{{{ typeeditorparams }}}">
|
||||
<img alt="" class="icon" src="{{{ typeicon }}}"> {{ typename }}
|
||||
</a>
|
||||
{{/typeeditorparams}}
|
||||
{{/types}}
|
||||
{{/contenttypes}}
|
||||
</div>
|
||||
</div>
|
|
@ -507,4 +507,100 @@ class core_contentbank_testcase extends advanced_testcase {
|
|||
// Check there's no error when trying to move content context from an empty content bank.
|
||||
$this->assertTrue($cb->delete_contents($systemcontext, $coursecontext));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for get_contenttypes_with_capability_feature.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_contenttypes_with_capability_feature_provider(): array {
|
||||
return [
|
||||
'no-contenttypes_enabled' => [
|
||||
'contenttypesenabled' => [],
|
||||
'contenttypescanfeature' => [],
|
||||
],
|
||||
'contenttype_enabled_noeditable' => [
|
||||
'contenttypesenabled' => ['testable'],
|
||||
'contenttypescanfeature' => [],
|
||||
],
|
||||
'contenttype_enabled_editable' => [
|
||||
'contenttypesenabled' => ['testable'],
|
||||
'contenttypescanfeature' => ['testable'],
|
||||
],
|
||||
'no-contenttype_enabled_editable' => [
|
||||
'contenttypesenabled' => [],
|
||||
'contenttypescanfeature' => ['testable'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for get_contenttypes_with_capability_feature() function.
|
||||
*
|
||||
* @dataProvider get_contenttypes_with_capability_feature_provider
|
||||
* @param array $contenttypesenabled Content types enabled.
|
||||
* @param array $contenttypescanfeature Content types the user has the permission to use the feature.
|
||||
*
|
||||
* @covers ::get_contenttypes_with_capability_feature
|
||||
*/
|
||||
public function test_get_contenttypes_with_capability_feature(array $contenttypesenabled, array $contenttypescanfeature): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$cb = new contentbank();
|
||||
|
||||
$plugins = [];
|
||||
|
||||
// Content types not enabled where the user has permission to use a feature.
|
||||
if (empty($contenttypesenabled) && !empty($contenttypescanfeature)) {
|
||||
$enabled = false;
|
||||
|
||||
// Mock core_plugin_manager class and the method get_plugins_of_type.
|
||||
$pluginmanager = $this->getMockBuilder(\core_plugin_manager::class)
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(['get_plugins_of_type'])
|
||||
->getMock();
|
||||
|
||||
// Replace protected singletoninstance reference (core_plugin_manager property) with mock object.
|
||||
$ref = new \ReflectionProperty(\core_plugin_manager::class, 'singletoninstance');
|
||||
$ref->setAccessible(true);
|
||||
$ref->setValue(null, $pluginmanager);
|
||||
|
||||
// Return values of get_plugins_of_type method.
|
||||
foreach ($contenttypescanfeature as $contenttypepluginname) {
|
||||
$contenttypeplugin = new \stdClass();
|
||||
$contenttypeplugin->name = $contenttypepluginname;
|
||||
$contenttypeplugin->type = 'contenttype';
|
||||
// Add the feature to the fake content type.
|
||||
$classname = "\\contenttype_$contenttypepluginname\\contenttype";
|
||||
$classname::$featurestotest = ['test2'];
|
||||
$plugins[] = $contenttypeplugin;
|
||||
}
|
||||
|
||||
// Set expectations and return values.
|
||||
$pluginmanager->expects($this->once())
|
||||
->method('get_plugins_of_type')
|
||||
->with('contenttype')
|
||||
->willReturn($plugins);
|
||||
} else {
|
||||
$enabled = true;
|
||||
// Get access to private property enabledcontenttypes.
|
||||
$rc = new \ReflectionClass(\core_contentbank\contentbank::class);
|
||||
$rcp = $rc->getProperty('enabledcontenttypes');
|
||||
$rcp->setAccessible(true);
|
||||
|
||||
foreach ($contenttypesenabled as $contenttypename) {
|
||||
$plugins["\\contenttype_$contenttypename\\contenttype"] = $contenttypename;
|
||||
// Add to the testable contenttype the feature to test.
|
||||
if (in_array($contenttypename, $contenttypescanfeature)) {
|
||||
$classname = "\\contenttype_$contenttypename\\contenttype";
|
||||
$classname::$featurestotest = ['test2'];
|
||||
}
|
||||
}
|
||||
// Set as enabled content types only those in the test.
|
||||
$rcp->setValue($cb, $plugins);
|
||||
}
|
||||
|
||||
$actual = $cb->get_contenttypes_with_capability_feature('test2', null, $enabled);
|
||||
$this->assertEquals($contenttypescanfeature, array_values($actual));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,9 @@ class contenttype extends \core_contentbank\contenttype {
|
|||
/** Feature for testing */
|
||||
const CAN_TEST = 'test';
|
||||
|
||||
/** @var array Additional features for testing */
|
||||
public static $featurestotest;
|
||||
|
||||
/**
|
||||
* Returns the HTML code to render the icon for content bank contents.
|
||||
*
|
||||
|
@ -55,7 +58,13 @@ class contenttype extends \core_contentbank\contenttype {
|
|||
* @return array
|
||||
*/
|
||||
protected function get_implemented_features(): array {
|
||||
return [self::CAN_TEST];
|
||||
$features = [self::CAN_TEST];
|
||||
|
||||
if (!empty(self::$featurestotest)) {
|
||||
$features = array_merge($features, self::$featurestotest);
|
||||
}
|
||||
|
||||
return $features;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,4 +75,29 @@ class contenttype extends \core_contentbank\contenttype {
|
|||
public function get_manageable_extensions(): array {
|
||||
return ['.txt', '.png', '.h5p'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of different types of the given content type.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_contenttype_types(): array {
|
||||
$type = new \stdClass();
|
||||
$type->typename = 'testable';
|
||||
|
||||
return [$type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, so the user has permission on the feature.
|
||||
*
|
||||
* @return bool True if content could be edited or created. False otherwise.
|
||||
*/
|
||||
final public function can_test2(): bool {
|
||||
if (!$this->is_feature_supported('test2')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
$string['author'] = 'Author';
|
||||
$string['contentbank'] = 'Content bank';
|
||||
$string['close'] = 'Close';
|
||||
$string['contentdeleted'] = 'The content has been deleted.';
|
||||
$string['contentname'] = 'Content name';
|
||||
$string['contentnotdeleted'] = 'An error was encountered while trying to delete the content.';
|
||||
|
@ -45,6 +46,7 @@ $string['file_help'] = 'Files may be stored in the content bank for use in cours
|
|||
$string['itemsfound'] = '{$a} items found';
|
||||
$string['lastmodified'] = 'Last modified';
|
||||
$string['name'] = 'Content';
|
||||
$string['nocontenttypes'] = 'No content types available';
|
||||
$string['nopermissiontodelete'] = 'You do not have permission to delete content.';
|
||||
$string['nopermissiontomanage'] = 'You do not have permission to manage content.';
|
||||
$string['privacy:metadata:content:contenttype'] = 'The contenttype plugin of the content in the content bank.';
|
||||
|
|
|
@ -156,6 +156,7 @@ $string['contentbank:deleteowncontent'] = 'Delete content from own content bank'
|
|||
$string['contentbank:manageanycontent'] = 'Manage any content from the content bank (rename, move, publish, share, etc.)';
|
||||
$string['contentbank:manageowncontent'] = 'Manage content from own content bank (rename, move, publish, share, etc.)';
|
||||
$string['contentbank:upload'] = 'Upload new content in the content bank';
|
||||
$string['contentbank:useeditor'] = 'Create or edit content using a content type editor';
|
||||
$string['context'] = 'Context';
|
||||
$string['course:activityvisibility'] = 'Hide/show activities';
|
||||
$string['course:bulkmessaging'] = 'Send a message to many people';
|
||||
|
|
|
@ -2544,4 +2544,16 @@ $capabilities = array(
|
|||
'editingteacher' => CAP_ALLOW,
|
||||
)
|
||||
],
|
||||
|
||||
// Allow users to create/edit content within the content bank.
|
||||
'moodle/contentbank:useeditor' => [
|
||||
'riskbitmask' => RISK_SPAM,
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_COURSE,
|
||||
'archetypes' => array(
|
||||
'manager' => CAP_ALLOW,
|
||||
'coursecreator' => CAP_ALLOW,
|
||||
'editingteacher' => CAP_ALLOW,
|
||||
)
|
||||
],
|
||||
);
|
||||
|
|
|
@ -121,3 +121,8 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cb-toolbar .dropdown-scrollable {
|
||||
max-height: 190px;
|
||||
overflow-y: auto;
|
||||
}
|
|
@ -12944,6 +12944,10 @@ table.calendartable caption {
|
|||
.content-bank-container.view-list .cb-btnsort.dir-desc .desc {
|
||||
display: block; }
|
||||
|
||||
.cb-toolbar .dropdown-scrollable {
|
||||
max-height: 190px;
|
||||
overflow-y: auto; }
|
||||
|
||||
/* course.less */
|
||||
/* COURSE CONTENT */
|
||||
.section_add_menus {
|
||||
|
|
|
@ -13156,6 +13156,10 @@ table.calendartable caption {
|
|||
.content-bank-container.view-list .cb-btnsort.dir-desc .desc {
|
||||
display: block; }
|
||||
|
||||
.cb-toolbar .dropdown-scrollable {
|
||||
max-height: 190px;
|
||||
overflow-y: auto; }
|
||||
|
||||
/* course.less */
|
||||
/* COURSE CONTENT */
|
||||
.section_add_menus {
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2020052700.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2020052700.01; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
$release = '3.9dev+ (Build: 20200527)'; // Human-friendly version name
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue