Skip to content

Commit

Permalink
MDL-74590 contentbank: add custom fields to content bank
Browse files Browse the repository at this point in the history
  • Loading branch information
danielneis committed Jul 23, 2024
1 parent fd487cd commit 659e9b8
Show file tree
Hide file tree
Showing 18 changed files with 485 additions and 5 deletions.
6 changes: 6 additions & 0 deletions admin/settings/plugins.php
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,12 @@
$temp = new admin_settingpage('managecontentbanktypes', new lang_string('managecontentbanktypes'));
$temp->add(new admin_setting_managecontentbankcontenttypes());
$ADMIN->add('contentbanksettings', $temp);
$ADMIN->add('contentbanksettings',
new admin_externalpage('contentbank', new lang_string('contentbankcustomfields'),
$CFG->wwwroot . '/contentbank/customfield.php',
'moodle/contentbank:configurecustomfields'
)
);
$plugins = core_plugin_manager::instance()->get_plugins_of_type('contenttype');
foreach ($plugins as $plugin) {
/** @var \core\plugininfo\contentbank $plugin */
Expand Down
10 changes: 10 additions & 0 deletions contentbank/classes/content.php
Original file line number Diff line number Diff line change
Expand Up @@ -397,4 +397,14 @@ public function is_view_allowed(): bool {
$this->get_visibility() == self::VISIBILITY_PUBLIC ||
has_capability('moodle/contentbank:viewunlistedcontent', $context);
}

/**
* Checks if there are any custom field related to this content.
*
* @return bool True if there is at least one populated field.
*/
public function has_custom_fields(): bool {
$handler = \core_contentbank\customfield\content_handler::create();
return !empty($handler->get_instance_data($this->get_id()));
}
}
7 changes: 7 additions & 0 deletions contentbank/classes/contenttype.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,17 @@ public function get_view_url(content $content): string {
* @return string HTML code to include in view.php.
*/
public function get_view_content(content $content): string {
global $PAGE;

// Trigger an event for viewing this content.
$event = contentbank_content_viewed::create_from_record($content->get_content());
$event->trigger();

if ($content->has_custom_fields()) {
$renderer = $PAGE->get_renderer('core');
$renderable = new \core_contentbank\output\customfields($content);
return $renderer->render($renderable);
}
return '';
}

Expand Down
186 changes: 186 additions & 0 deletions contentbank/classes/customfield/content_handler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
<?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/>.

namespace core_contentbank\customfield;

use core_customfield\api;
use core_customfield\field_controller;

/**
* Content handler for content bank custom fields
*
* @package core_contentbank
* @copyright 2024 Daniel Neis Araujo <[email protected]>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class content_handler extends \core_customfield\handler {

/**
* @var content_handler
*/
static protected $singleton;

/**
* @var \context
*/
protected $parentcontext;

/** @var int Field is displayed in the content bank edit page, visible to everybody */
const VISIBLETOALL = 2;
/** @var int Field is not displayed in the content bank edit page */
const NOTVISIBLE = 0;

/**
* Returns a singleton
*
* @param int $itemid
* @return \core_contentbank\customfield\content_handler
*/
public static function create(int $itemid = 0): \core_contentbank\customfield\content_handler {
if (static::$singleton === null) {
self::$singleton = new static(0);
}
return self::$singleton;
}

/**
* Run reset code after unit tests to reset the singleton usage.
*/
public static function reset_caches(): void {
if (!PHPUNIT_TEST) {
throw new \coding_exception('This feature is only intended for use in unit tests');
}

static::$singleton = null;
}

/**
* The current user can configure custom fields on this component.
*
* @return bool true if the current can configure custom fields, false otherwise
*/
public function can_configure(): bool {
return has_capability('moodle/contentbank:configurecustomfields', $this->get_configuration_context());
}

/**
* The current user can edit custom fields on the content bank.
*
* @param field_controller $field
* @param int $instanceid id of the course to test edit permission
* @return bool true if the current can edit custom fields, false otherwise
*/
public function can_edit(field_controller $field, int $instanceid = 0): bool {
$context = $this->get_instance_context($instanceid);
return (!$field->get_configdata_property('locked') ||
has_capability('moodle/contentbank:changelockedcustomfields', $context));
}

/**
* The current user can view custom fields on the given course.
*
* @param field_controller $field
* @param int $instanceid id of the course to test edit permission
* @return bool true if the current can edit custom fields, false otherwise
*/
public function can_view(field_controller $field, int $instanceid): bool {
$visibility = $field->get_configdata_property('visibility');
if ($visibility == self::NOTVISIBLE) {
return false;
} else {
return true;
}
}

/**
* Context that should be used for new categories created by this handler
*
* @return \context the context for configuration
*/
public function get_configuration_context(): \context {
return \context_system::instance();
}

/**
* URL for configuration of the fields on this handler.
*
* @return \moodle_url The URL to configure custom fields for this component
*/
public function get_configuration_url(): \moodle_url {
return new \moodle_url('/contentbank/customfield.php');
}

/**
* Returns the context for the data associated with the given instanceid.
*
* @param int $instanceid id of the record to get the context for
* @return \context the context for the given record
*/
public function get_instance_context(int $instanceid = 0): \context {
global $DB;
return \context::instance_by_id($DB->get_field('contentbank_content', 'contextid', ['id' => $instanceid]));
}

/**
* Allows to add custom controls to the field configuration form that will be saved in configdata
*
* @param \MoodleQuickForm $mform
*/
public function config_form_definition(\MoodleQuickForm $mform) {
$mform->addElement('header', 'content_handler_header', get_string('customfieldsettings', 'core_course'));
$mform->setExpanded('content_handler_header', true);

// If field is locked.
$mform->addElement('selectyesno', 'configdata[locked]', get_string('customfield_islocked', 'core_course'));
$mform->addHelpButton('configdata[locked]', 'customfield_islocked', 'core_course');

// Field data visibility.
$visibilityoptions = [self::VISIBLETOALL => get_string('customfield_visibletoall', 'core_course'),
self::NOTVISIBLE => get_string('customfield_notvisible', 'core_course')];
$mform->addElement('select', 'configdata[visibility]', get_string('customfield_visibility', 'core_course'),
$visibilityoptions);
$mform->addHelpButton('configdata[visibility]', 'customfield_visibility', 'core_course');
}

/**
* Creates or updates custom field data.
*
* @param \restore_task $task
* @param array $data
*/
public function restore_instance_data_from_backup(\restore_task $task, array $data) {
$courseid = $task->get_courseid();
$context = $this->get_instance_context($courseid);
$editablefields = $this->get_editable_fields($courseid);
$records = api::get_instance_fields_data($editablefields, $courseid);
$target = $task->get_target();
$override = ($target != \backup::TARGET_CURRENT_ADDING && $target != \backup::TARGET_EXISTING_ADDING);

foreach ($records as $d) {
$field = $d->get_field();
if ($field->get('shortname') === $data['shortname'] && $field->get('type') === $data['type']) {
if (!$d->get('id') || $override) {
$d->set($d->datafield(), $data['value']);
$d->set('value', $data['value']);
$d->set('valueformat', $data['valueformat']);
$d->set('contextid', $context->id);
$d->save();
}
return;
}
}
}
}
6 changes: 6 additions & 0 deletions contentbank/classes/external/copy_content.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ public static function execute(int $contentid, string $name): array {
$crecord->name = $params['name'];

if ($content = $contenttype->create_content($crecord)) {

$handler = \core_contentbank\customfield\content_handler::create();
$handler->instance_form_before_set_data($record);
$record->id = $content->get_id();
$handler->instance_form_save($record);

$fs = get_file_storage();
$files = $fs->get_area_files($context->id, 'contentbank', 'public', $params['contentid'], 'itemid, filepath,
filename', false);
Expand Down
19 changes: 17 additions & 2 deletions contentbank/classes/form/edit_content.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ abstract class edit_content extends moodleform {
* @param string $method Form method.
*/
public function __construct(string $action = null, array $customdata = null, string $method = 'post') {
parent::__construct($action, $customdata, $method);
$this->contextid = $customdata['contextid'];
$this->plugin = $customdata['plugin'];
$this->id = $customdata['id'];
$this->id = $customdata['id'] ?? 0;
parent::__construct($action, $customdata, $method);

$mform =& $this->_form;
$mform->addElement('hidden', 'contextid', $this->contextid);
Expand All @@ -72,6 +72,21 @@ public function __construct(string $action = null, array $customdata = null, str
$this->_form->setType('id', PARAM_INT);
}

/**
* Add elements to form
*/
public function definition() {
global $DB;
// Add custom fields to the form.
$content = $DB->get_record('contentbank_content', ['id' => $this->id]);
$handler = \core_contentbank\customfield\content_handler::create();
$handler->instance_form_definition($this->_form, $this->id);
if ($content) {
$handler->instance_form_before_set_data($content);
}
$this->set_data($content);
}

/**
* Overrides formslib's add_action_buttons() method.
*
Expand Down
71 changes: 71 additions & 0 deletions contentbank/classes/output/customfields.php
Original file line number Diff line number Diff line change
@@ -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/>.

/**
* Content bank custom fields.
*
* @package core_contentbank
* @copyright 2022 Daniel Neis Araujo <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

namespace core_contentbank\output;

use moodle_url;
use renderable;
use templatable;
use renderer_base;
use core_contentbank\content;

/**
* Content bank Custom Fields renderable class.
*
* @package core_contentbank
* @copyright 2022 Daniel Neis Araujo <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class customfields implements renderable, templatable {

/**
* Constructor.
*
* @param \core_contentbank\content $content The content object.
*/
public function __construct(content $content) {
$this->content = $content;
}

/**
* Export the data.
*
* @param renderer_base $output
* @return stdClass
*/
public function export_for_template(renderer_base $output) {
global $DB;

$context = new \stdClass();

$context->url = $this->content->get_file_url();
$context->name = $this->content->get_name();

$handler = \core_contentbank\customfield\content_handler::create();
$customfields = $handler->get_instance_data($this->content->get_id());
$context->data = $handler->display_custom_fields_data($customfields);

return $context;
}
}
4 changes: 4 additions & 0 deletions contentbank/classes/output/viewcontent.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ public function export_for_template(renderer_base $output): stdClass {
$contenthtml = $this->contenttype->get_view_content($this->content);
$data->contenthtml = $contenthtml;

$handler = \core_contentbank\customfield\content_handler::create();
$customfields = $handler->get_instance_data($this->content->get_id());
$data->customfieldshtml = $handler->display_custom_fields_data($customfields);

// Check if the user can edit this content type.
if ($this->contenttype->can_edit($this->content)) {
$data->usercanedit = true;
Expand Down
Loading

0 comments on commit 659e9b8

Please sign in to comment.