MDL-75146 mod_data: migrate templates editor to mustache
This commit is contained in:
committed by
Sara Arjona
parent
c6db008496
commit
e2da14bbb8
@@ -16,11 +16,13 @@
|
||||
|
||||
namespace mod_data;
|
||||
|
||||
use context_module;
|
||||
use cm_info;
|
||||
use context_module;
|
||||
use completion_info;
|
||||
use data_field_base;
|
||||
use mod_data\event\course_module_viewed;
|
||||
use mod_data\event\template_viewed;
|
||||
use mod_data\event\template_updated;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
@@ -38,6 +40,23 @@ class manager {
|
||||
/** Pluginname name. */
|
||||
const PLUGIN = 'mod_data';
|
||||
|
||||
/** Template list with their files required to save the information of a preset. */
|
||||
const TEMPLATES_LIST = [
|
||||
'listtemplate' => 'listtemplate.html',
|
||||
'singletemplate' => 'singletemplate.html',
|
||||
'asearchtemplate' => 'asearchtemplate.html',
|
||||
'addtemplate' => 'addtemplate.html',
|
||||
'rsstemplate' => 'rsstemplate.html',
|
||||
'csstemplate' => 'csstemplate.css',
|
||||
'jstemplate' => 'jstemplate.js',
|
||||
'listtemplateheader' => 'listtemplateheader.html',
|
||||
'listtemplatefooter' => 'listtemplatefooter.html',
|
||||
'rsstitletemplate' => 'rsstitletemplate.html',
|
||||
];
|
||||
|
||||
/** @var string plugin path. */
|
||||
private $path;
|
||||
|
||||
/** @var stdClass course_module record. */
|
||||
private $instance;
|
||||
|
||||
@@ -47,6 +66,11 @@ class manager {
|
||||
/** @var cm_info course_modules record. */
|
||||
private $cm;
|
||||
|
||||
/** @var array the current data_fields records.
|
||||
* Do not acces this attribute directly, use $this->get_field_records instead
|
||||
*/
|
||||
private $_fieldrecords = null;
|
||||
|
||||
/**
|
||||
* Class contructor.
|
||||
*
|
||||
@@ -54,10 +78,12 @@ class manager {
|
||||
* @param stdClass $instance activity instance object.
|
||||
*/
|
||||
public function __construct(cm_info $cm, stdClass $instance) {
|
||||
global $CFG;
|
||||
$this->cm = $cm;
|
||||
$this->instance = $instance;
|
||||
$this->context = context_module::instance($cm->id);
|
||||
$this->instance->cmidnumber = $cm->idnumber;
|
||||
$this->path = $CFG->dirroot . '/mod/' . self::MODULE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,4 +193,114 @@ class manager {
|
||||
$event->add_record_snapshot(self::MODULE, $this->instance);
|
||||
$event->trigger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the database fields.
|
||||
*
|
||||
* @return data_field_base[] the field instances.
|
||||
*/
|
||||
public function get_fields(): array {
|
||||
$result = [];
|
||||
$fieldrecords = $this->get_field_records();
|
||||
foreach ($fieldrecords as $fieldrecord) {
|
||||
$result[$fieldrecord->id] = $this->get_field($fieldrecord);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field records (the current data_fields records).
|
||||
*
|
||||
* @return stdClass[] an array of records
|
||||
*/
|
||||
public function get_field_records() {
|
||||
global $DB;
|
||||
if ($this->_fieldrecords === null) {
|
||||
$this->_fieldrecords = $DB->get_records('data_fields', ['dataid' => $this->instance->id]);
|
||||
}
|
||||
return $this->_fieldrecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a specific field instance from a field record.
|
||||
*
|
||||
* @param stdClass $fieldrecord the fieldrecord to convert
|
||||
* @return data_field_base the data field class instance
|
||||
*/
|
||||
public function get_field(stdClass $fieldrecord): data_field_base {
|
||||
$filepath = "{$this->path}/field/{$fieldrecord->type}/field.class.php";
|
||||
$classname = "data_field_{$fieldrecord->type}";
|
||||
if (!file_exists($filepath) || !class_exists($classname)) {
|
||||
return new data_field_base($fieldrecord, $this->instance, $this->cm);
|
||||
}
|
||||
require_once($filepath);
|
||||
$newfield = new $classname($fieldrecord, $this->instance, $this->cm);
|
||||
return $newfield;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a specific template.
|
||||
*
|
||||
* NOTE: this method returns a default template if the module template is empty.
|
||||
* However, it won't update the template database field.
|
||||
*
|
||||
* @param string $templatename
|
||||
* @param array $options extra display options array
|
||||
* @return template the template instance
|
||||
*/
|
||||
public function get_template(string $templatename, array $options = []): template {
|
||||
if ($templatename == 'single') {
|
||||
$templatename == 'singletemplate';
|
||||
}
|
||||
$instance = $this->instance;
|
||||
$templatestr = $instance->{$templatename} ?? '';
|
||||
if (empty($templatestr)) {
|
||||
$templatestr = data_generate_default_template($instance, $templatename, 0, false, false);
|
||||
}
|
||||
// Some templates have extra options.
|
||||
if ($templatename == 'singletemplate') {
|
||||
$options['comments'] = true;
|
||||
$options['ratings'] = true;
|
||||
}
|
||||
return new template($this, $templatestr, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the database templates.
|
||||
*
|
||||
* @param stdClass $newtemplates an object with all the new templates
|
||||
* @return bool if updated successfully.
|
||||
*/
|
||||
public function update_templates(stdClass $newtemplates) {
|
||||
global $DB;
|
||||
$record = (object)[
|
||||
'id' => $this->instance->id,
|
||||
];
|
||||
foreach (self::TEMPLATES_LIST as $templatename => $templatefile) {
|
||||
if (!isset($newtemplates->{$templatename})) {
|
||||
continue;
|
||||
}
|
||||
$record->{$templatename} = $newtemplates->{$templatename};
|
||||
}
|
||||
|
||||
// The add entry form cannot repeat tags.
|
||||
if (isset($record->addtemplate) && !data_tags_check($this->instance->id, $record->addtemplate)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$DB->update_record(self::MODULE, $record);
|
||||
$this->instance = $DB->get_record(self::MODULE, ['id' => $this->cm->instance], '*', MUST_EXIST);
|
||||
|
||||
// Trigger an event for saving the templates.
|
||||
$event = template_updated::create(array(
|
||||
'context' => $this->context,
|
||||
'courseid' => $this->cm->course,
|
||||
'other' => array(
|
||||
'dataid' => $this->instance->id,
|
||||
)
|
||||
));
|
||||
$event->trigger();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
<?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 mod_data\output;
|
||||
|
||||
use templatable;
|
||||
use renderable;
|
||||
use mod_data\manager;
|
||||
use moodle_url;
|
||||
use texteditor;
|
||||
|
||||
/**
|
||||
* Renderable class for template editor.
|
||||
*
|
||||
* @package mod_data
|
||||
* @copyright 2022 Ferran Recio <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class template_editor implements templatable, renderable {
|
||||
|
||||
/** @var manager manager instance. */
|
||||
private $manager;
|
||||
|
||||
/** @var string the template name. */
|
||||
private $templatename;
|
||||
|
||||
/**
|
||||
* The class constructor.
|
||||
*
|
||||
* @param manager $manager the activity instance manager
|
||||
* @param string $templatename the template to edit
|
||||
*/
|
||||
public function __construct(manager $manager, string $templatename) {
|
||||
$this->manager = $manager;
|
||||
$this->templatename = $templatename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the data for the mustache template.
|
||||
*
|
||||
* @param \renderer_base $output renderer to be used to render the action bar elements.
|
||||
* @return array
|
||||
*/
|
||||
public function export_for_template(\renderer_base $output): array {
|
||||
$instance = $this->manager->get_instance();
|
||||
$cm = $this->manager->get_coursemodule();
|
||||
|
||||
$data = [
|
||||
'title' => get_string('header' . $this->templatename, 'data'),
|
||||
'sesskey' => sesskey(),
|
||||
'disableeditor' => true,
|
||||
'url' => new moodle_url('/mod/data/templates.php', ['id' => $cm->id, 'mode' => $this->templatename]),
|
||||
];
|
||||
|
||||
// Determine whether to use HTML editors.
|
||||
if (($this->templatename === 'csstemplate') || ($this->templatename === 'jstemplate')) {
|
||||
$usehtmleditor = false;
|
||||
} else {
|
||||
$usehtmleditor = data_get_config($instance, "editor_{$this->templatename}", true);
|
||||
}
|
||||
$data['usehtmleditor'] = $usehtmleditor;
|
||||
|
||||
$tools = new template_editor_tools($this->manager, $this->templatename);
|
||||
$data['toolbar'] = $tools->export_for_template($output);
|
||||
$data['editors'] = $this->get_editors_data($usehtmleditor);
|
||||
|
||||
// Some templates cannot enable the wysiwyg editor.
|
||||
if ($this->templatename == 'csstemplate' || $this->templatename == 'jstemplate') {
|
||||
$data['disableeditor'] = false;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the editors data.
|
||||
*
|
||||
* @param bool $usehtmleditor if the user wants wysiwyg editor or not
|
||||
* @return array editors data
|
||||
*/
|
||||
private function get_editors_data(bool $usehtmleditor): array {
|
||||
global $PAGE;
|
||||
|
||||
$result = [];
|
||||
$instance = $this->manager->get_instance();
|
||||
|
||||
// Setup editor.
|
||||
editors_head_setup();
|
||||
$PAGE->requires->js_call_amd(
|
||||
'mod_data/templateseditor',
|
||||
'init',
|
||||
['d' => $instance->id, 'mode' => $this->templatename]
|
||||
);
|
||||
|
||||
if ($usehtmleditor) {
|
||||
$format = FORMAT_HTML;
|
||||
} else {
|
||||
$format = FORMAT_PLAIN;
|
||||
}
|
||||
|
||||
$editor = editors_get_preferred_editor($format);
|
||||
|
||||
// Add editors.
|
||||
if ($this->templatename == 'listtemplate') {
|
||||
$result[] = $this->generate_editor_data(
|
||||
$editor,
|
||||
'header',
|
||||
'listtemplateheader',
|
||||
$instance->listtemplateheader
|
||||
);
|
||||
$maineditorname = 'multientry';
|
||||
} else {
|
||||
$maineditorname = $this->templatename;
|
||||
}
|
||||
|
||||
$value = $instance->{$this->templatename} ?? '';
|
||||
$result[] = $this->generate_editor_data(
|
||||
$editor,
|
||||
$maineditorname,
|
||||
$this->templatename,
|
||||
$value
|
||||
);
|
||||
|
||||
if ($this->templatename == 'listtemplate') {
|
||||
$result[] = $this->generate_editor_data(
|
||||
$editor,
|
||||
'footer',
|
||||
'listtemplatefooter',
|
||||
$instance->listtemplatefooter
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->templatename == 'rsstemplate') {
|
||||
$result[] = $this->generate_editor_data(
|
||||
$editor,
|
||||
'rsstitletemplate',
|
||||
'rsstitletemplate',
|
||||
$instance->rsstitletemplate
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a single editor data.
|
||||
*
|
||||
* @param texteditor $editor the edtitor object
|
||||
* @param string $name the editor name
|
||||
* @param string $fieldname the field name
|
||||
* @param string|null $value the current value
|
||||
* @return array the editor data
|
||||
*/
|
||||
private function generate_editor_data(
|
||||
texteditor $editor,
|
||||
string $name,
|
||||
string $fieldname,
|
||||
?string $value
|
||||
): array {
|
||||
$options = [
|
||||
'trusttext' => false,
|
||||
'forcehttps' => false,
|
||||
'subdirs' => false,
|
||||
'maxfiles' => 0,
|
||||
'maxbytes' => 0,
|
||||
'changeformat' => 0,
|
||||
'noclean' => false,
|
||||
];
|
||||
|
||||
$result = [
|
||||
'name' => get_string($name, 'data'),
|
||||
'fieldname' => $fieldname,
|
||||
'value' => $value,
|
||||
];
|
||||
$editor->set_text($value);
|
||||
$editor->use_editor($fieldname, $options);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -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/>.
|
||||
|
||||
namespace mod_data\output;
|
||||
|
||||
use templatable;
|
||||
use renderable;
|
||||
use core_tag_tag;
|
||||
use mod_data\manager;
|
||||
use moodle_url;
|
||||
|
||||
/**
|
||||
* Renderable class for template editor tools.
|
||||
*
|
||||
* @package mod_data
|
||||
* @copyright 2022 Ferran Recio <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class template_editor_tools implements templatable, renderable {
|
||||
|
||||
/** @var manager manager instance. */
|
||||
private $manager;
|
||||
|
||||
/** @var string the template name. */
|
||||
private $templatename;
|
||||
|
||||
/**
|
||||
* The class constructor.
|
||||
*
|
||||
* @param manager $manager the activity instance manager
|
||||
* @param string $templatename the template to edit
|
||||
*/
|
||||
public function __construct(manager $manager, string $templatename) {
|
||||
$this->manager = $manager;
|
||||
$this->templatename = $templatename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the data for the mustache template.
|
||||
*
|
||||
* @param \renderer_base $output renderer to be used to render the action bar elements.
|
||||
* @return array
|
||||
*/
|
||||
public function export_for_template(\renderer_base $output): array {
|
||||
$tools = [
|
||||
$this->get_field_tags($this->templatename),
|
||||
$this->get_field_id_tags($this->templatename),
|
||||
$this->get_action_tags($this->templatename),
|
||||
$this->get_other_tags($this->templatename),
|
||||
];
|
||||
$tools = array_filter($tools, static function ($value) {
|
||||
return !empty($value['tags']);
|
||||
});
|
||||
return [
|
||||
'toolshelp' => $output->help_icon('availabletags', 'data'),
|
||||
'hastools' => !empty($tools),
|
||||
'tools' => array_values($tools),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field template tags.
|
||||
*
|
||||
* @param string $templatename the template name
|
||||
* @return array|null array of tags.
|
||||
*/
|
||||
protected function get_field_tags(string $templatename): array {
|
||||
$name = get_string('fields', 'data');
|
||||
if ($templatename == 'csstemplate' || $templatename == 'jstemplate') {
|
||||
return $this->get_optgroup_data($name, []);
|
||||
}
|
||||
$taglist = [];
|
||||
$fields = $this->manager->get_fields();
|
||||
foreach ($fields as $field) {
|
||||
$fieldname = $field->get_name();
|
||||
$taglist["[[$fieldname]]"] = $fieldname;
|
||||
}
|
||||
return $this->get_optgroup_data($name, $taglist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field IDs template tags.
|
||||
*
|
||||
* @param string $templatename the template name
|
||||
* @return array|null array of tags.
|
||||
*/
|
||||
protected function get_field_id_tags(string $templatename): array {
|
||||
$name = get_string('fieldids', 'data');
|
||||
if ($templatename != 'addtemplate') {
|
||||
return $this->get_optgroup_data($name, []);
|
||||
}
|
||||
$taglist = [];
|
||||
// Field IDs.
|
||||
$fields = $this->manager->get_fields();
|
||||
foreach ($fields as $field) {
|
||||
$fieldname = $field->get_name();
|
||||
$taglist["[[$fieldname#id]]"] = "$fieldname id";
|
||||
}
|
||||
return $this->get_optgroup_data($name, $taglist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field action tags.
|
||||
*
|
||||
* @param string $templatename the template name
|
||||
* @return array|null array of tags.
|
||||
*/
|
||||
protected function get_action_tags(string $templatename = null): array {
|
||||
$name = get_string('actions');
|
||||
if ($templatename == 'addtemplate' || $templatename == 'asearchtemplate') {
|
||||
return $this->get_optgroup_data($name, []);
|
||||
}
|
||||
$taglist = [
|
||||
'##edit##' => get_string('edit', 'data'),
|
||||
'##delete##' => get_string('delete', 'data'),
|
||||
'##approve##' => get_string('approve', 'data'),
|
||||
'##disapprove##' => get_string('disapprove', 'data'),
|
||||
];
|
||||
if ($templatename != 'rsstemplate') {
|
||||
$taglist['##export##'] = get_string('export', 'data');
|
||||
}
|
||||
if ($templatename != 'singletemplate') {
|
||||
$taglist['##more##'] = get_string('more', 'data');
|
||||
$taglist['##moreurl##'] = get_string('moreurl', 'data');
|
||||
$taglist['##delcheck##'] = get_string('delcheck', 'data');
|
||||
}
|
||||
return $this->get_optgroup_data($name, $taglist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the available other tags
|
||||
*
|
||||
* @param string $templatename the template name
|
||||
* @return array associative array of tags => tag name
|
||||
*/
|
||||
protected function get_other_tags(string $templatename = null): array {
|
||||
$name = get_string('other', 'data');
|
||||
$taglist = [];
|
||||
if ($templatename == 'asearchtemplate') {
|
||||
$taglist['##firstname##'] = get_string('firstname');
|
||||
$taglist['##lastname##'] = get_string('lastname');
|
||||
return $this->get_optgroup_data($name, $taglist);
|
||||
}
|
||||
if (core_tag_tag::is_enabled('mod_data', 'data_records')) {
|
||||
$taglist['##tags##'] = get_string('tags');
|
||||
}
|
||||
if ($templatename == 'addtemplate') {
|
||||
return $this->get_optgroup_data($name, $taglist);
|
||||
}
|
||||
$taglist['##timeadded##'] = get_string('timeadded', 'data');
|
||||
$taglist['##timemodified##'] = get_string('timemodified', 'data');
|
||||
$taglist['##user##'] = get_string('user');
|
||||
$taglist['##userpicture##'] = get_string('userpic');
|
||||
$taglist['##approvalstatus##'] = get_string('approvalstatus', 'data');
|
||||
$taglist['##id##'] = get_string('id', 'data');
|
||||
|
||||
if ($templatename == 'singletemplate') {
|
||||
return $this->get_optgroup_data($name, $taglist);
|
||||
}
|
||||
|
||||
$taglist['##comments##'] = get_string('comments', 'data');
|
||||
|
||||
return $this->get_optgroup_data($name, $taglist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a valid optgroup data.
|
||||
*
|
||||
* @param string $name the optgroup name
|
||||
* @param array $taglist the indexed array of taglists ($tag => $tagname)
|
||||
* @return array of optgroup data
|
||||
*/
|
||||
protected function get_optgroup_data (string $name, array $taglist): array {
|
||||
$tags = [];
|
||||
foreach ($taglist as $tag => $tagname) {
|
||||
$tags[] = [
|
||||
'tag' => "$tag",
|
||||
'tagname' => $tagname . ' - ' . $tag,
|
||||
];
|
||||
}
|
||||
return [
|
||||
'name' => $name,
|
||||
'tags' => $tags,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user