MDL-67810 core_contentbank: added dropdown menu to create content

This commit is contained in:
Víctor Déniz Falcón 2020-04-29 14:00:43 +01:00 committed by Victor Deniz Falcon
parent 68fd8d8bdf
commit 75f58cbfa2
16 changed files with 437 additions and 14 deletions

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;
}
}