Merge branch 'MDL-75498-master' of https://github.com/ferranrecio/moodle

This commit is contained in:
Andrew Nicols 2023-01-31 15:13:33 +08:00
commit 1f4794341b
30 changed files with 713 additions and 124 deletions

View File

@ -56,7 +56,7 @@ class template_editor_tools implements templatable, renderable {
public function export_for_template(\renderer_base $output): array { public function export_for_template(\renderer_base $output): array {
$tools = [ $tools = [
$this->get_field_tags($this->templatename), $this->get_field_tags($this->templatename),
$this->get_field_id_tags($this->templatename), $this->get_field_info_tags($this->templatename),
$this->get_action_tags($this->templatename), $this->get_action_tags($this->templatename),
$this->get_other_tags($this->templatename), $this->get_other_tags($this->templatename),
]; ];
@ -90,29 +90,30 @@ class template_editor_tools implements templatable, renderable {
$fieldname = $field->get_name(); $fieldname = $field->get_name();
$taglist["[[$fieldname]]"] = $fieldname; $taglist["[[$fieldname]]"] = $fieldname;
} }
$taglist['##otherfields##'] = get_string('otherfields', 'data');
return $this->get_optgroup_data($name, $taglist); return $this->get_optgroup_data($name, $taglist);
} }
/** /**
* Return the field IDs template tags. * Return the field information template tags.
* *
* @param string $templatename the template name * @param string $templatename the template name
* @return array|null array of tags. * @return array|null array of tags.
*/ */
protected function get_field_id_tags(string $templatename): array { protected function get_field_info_tags(string $templatename): array {
$name = get_string('fieldids', 'data'); $name = get_string('fieldsinformationtags', 'data');
if ($templatename != 'addtemplate') {
return $this->get_optgroup_data($name, []);
}
$taglist = []; $taglist = [];
// Field IDs.
$fields = $this->manager->get_fields(); $fields = $this->manager->get_fields();
foreach ($fields as $field) { foreach ($fields as $field) {
if ($field->type === 'unknown') { if ($field->type === 'unknown') {
continue; continue;
} }
$fieldname = $field->get_name(); $fieldname = $field->get_name();
$taglist["[[$fieldname#id]]"] = "$fieldname id"; if ($templatename == 'addtemplate') {
$taglist["[[$fieldname#id]]"] = get_string('fieldtagid', 'mod_data', $fieldname);
}
$taglist["[[$fieldname#name]]"] = get_string('fieldtagname', 'mod_data', $fieldname);
$taglist["[[$fieldname#description]]"] = get_string('fieldtagdescription', 'mod_data', $fieldname);
} }
return $this->get_optgroup_data($name, $taglist); return $this->get_optgroup_data($name, $taglist);
} }
@ -129,11 +130,11 @@ class template_editor_tools implements templatable, renderable {
return $this->get_optgroup_data($name, []); return $this->get_optgroup_data($name, []);
} }
$taglist = [ $taglist = [
'##actionsmenu##' => get_string('actionsmenu', 'data'),
'##edit##' => get_string('edit', 'data'), '##edit##' => get_string('edit', 'data'),
'##delete##' => get_string('delete', 'data'), '##delete##' => get_string('delete', 'data'),
'##approve##' => get_string('approve', 'data'), '##approve##' => get_string('approve', 'data'),
'##disapprove##' => get_string('disapprove', 'data'), '##disapprove##' => get_string('disapprove', 'data'),
'##actionsmenu##' => get_string('actionsmenu', 'data'),
]; ];
if ($templatename != 'rsstemplate') { if ($templatename != 'rsstemplate') {
$taglist['##export##'] = get_string('export', 'data'); $taglist['##export##'] = get_string('export', 'data');

View File

@ -19,6 +19,7 @@ namespace mod_data;
use action_menu; use action_menu;
use action_menu_link_secondary; use action_menu_link_secondary;
use core\output\checkbox_toggleall; use core\output\checkbox_toggleall;
use data_field_base;
use html_writer; use html_writer;
use mod_data\manager; use mod_data\manager;
use moodle_url; use moodle_url;
@ -79,6 +80,9 @@ class template {
/** @var array The mod_data fields. */ /** @var array The mod_data fields. */
protected $fields = []; protected $fields = [];
/** @var array All fields that are not present in the template content. */
protected $otherfields = [];
/** /**
* Class contructor. * Class contructor.
* *
@ -213,6 +217,13 @@ class template {
return; return;
} }
$this->tags = $matches['tags']; $this->tags = $matches['tags'];
// Check if some tag require some extra template scan.
foreach ($this->tags as $tagname) {
$methodname = "preprocess_tag_{$tagname}";
if (method_exists($this, $methodname)) {
$this->$methodname($templatecontent);
}
}
} }
/** /**
@ -309,9 +320,13 @@ class template {
$this->search, $this->search,
$field->display_browse_field($entry->id, $this->templatename) $field->display_browse_field($entry->id, $this->templatename)
); );
// Field id. // Other dynamic field information.
$pattern = '[[' . $field->field->name . '#id]]'; $pattern = '[[' . $field->field->name . '#id]]';
$result[$pattern] = $field->field->id; $result[$pattern] = $field->field->id;
$pattern = '[[' . $field->field->name . '#name]]';
$result[$pattern] = $field->field->name;
$pattern = '[[' . $field->field->name . '#description]]';
$result[$pattern] = $field->field->description;
} }
return $result; return $result;
} }
@ -707,6 +722,46 @@ class template {
return (string) $entry->id; return (string) $entry->id;
} }
/**
* Prepare otherfield tag scanning the present template fields.
*
* @param string $templatecontent the template content
*/
protected function preprocess_tag_otherfields(string $templatecontent) {
$otherfields = [];
$fields = $this->manager->get_fields();
foreach ($fields as $field) {
if (strpos($templatecontent, "[[" . $field->field->name . "]]") === false) {
$otherfields[] = $field;
}
}
$this->otherfields = $otherfields;
}
/**
* Returns the ##otherfields## tag replacement for an entry.
*
* @param stdClass $entry the entry object
* @param bool $canmanageentry if the current user can manage this entry
* @return string the tag replacement
*/
protected function get_tag_otherfields_replacement(stdClass $entry, bool $canmanageentry): string {
global $OUTPUT;
$fields = [];
foreach ($this->otherfields as $field) {
$fieldvalue = highlight(
$this->search,
$field->display_browse_field($entry->id, $this->templatename)
);
$fieldinfo = [
'fieldname' => $field->field->name,
'fieldcontent' => $fieldvalue,
];
$fields[] = $fieldinfo;
}
return $OUTPUT->render_from_template('mod_data/fields_otherfields', ['fields' => $fields]);
}
/** /**
* Returns the ##actionsmenu## tag replacement for an entry. * Returns the ##actionsmenu## tag replacement for an entry.
* *
@ -842,6 +897,8 @@ class template {
?int $entryid = null, ?int $entryid = null,
?stdClass $entrydata = null ?stdClass $entrydata = null
): string { ): string {
global $OUTPUT;
$manager = $this->manager; $manager = $this->manager;
$renderer = $manager->get_renderer(); $renderer = $manager->get_renderer();
$templatecontent = $this->templatecontent; $templatecontent = $this->templatecontent;
@ -864,34 +921,38 @@ class template {
$replacements = []; $replacements = [];
// Then we generate strings to replace. // Then we generate strings to replace.
$otherfields = [];
foreach ($possiblefields as $field) { foreach ($possiblefields as $field) {
// To skip unnecessary calls to display_add_field(). $fieldinput = $this->get_field_input($processeddata, $entryid, $entrydata, $field);
if (strpos($templatecontent, "[[" . $field->field->name . "]]") !== false) { if (strpos($templatecontent, "[[" . $field->field->name . "]]") !== false) {
// Replace the field tag. // Replace the field tag.
$patterns[] = "[[" . $field->field->name . "]]"; $patterns[] = "[[" . $field->field->name . "]]";
$errors = ''; $replacements[] = $fieldinput;
$fieldnotifications = $processeddata->fieldnotifications[$field->field->name] ?? []; } else {
if (!empty($fieldnotifications)) { // Is in another fields.
foreach ($fieldnotifications as $notification) { $otherfields[] = [
$errors .= $renderer->notification($notification); 'fieldname' => $field->field->name,
} 'fieldcontent' => $fieldinput,
} ];
$fielddisplay = '';
if ($field->type === 'unknown') {
if ($this->canmanageentries) { // Display notification for users that can manage entries.
$errors .= $renderer->notification(get_string('missingfieldtype', 'data',
(object)['name' => $field->field->name]));
}
} else {
$fielddisplay = $field->display_add_field($entryid, $entrydata);
}
$replacements[] = $errors . $fielddisplay;
} }
// Replace the field id tag. // Replace the field id tag.
$patterns[] = "[[" . $field->field->name . "#id]]"; $patterns[] = "[[" . $field->field->name . "#id]]";
$replacements[] = 'field_' . $field->field->id; $replacements[] = 'field_' . $field->field->id;
$patterns[] = '[[' . $field->field->name . '#name]]';
$replacements[] = $field->field->name;
$patterns[] = '[[' . $field->field->name . '#description]]';
$replacements[] = $field->field->description;
}
$patterns[] = "##otherfields##";
if (!empty($otherfields)) {
$replacements[] = $OUTPUT->render_from_template(
'mod_data/fields_otherfields',
['fields' => $otherfields]
);
} else {
$replacements[] = '';
} }
if (core_tag_tag::is_enabled('mod_data', 'data_records')) { if (core_tag_tag::is_enabled('mod_data', 'data_records')) {
@ -902,4 +963,42 @@ class template {
$result .= str_ireplace($patterns, $replacements, $templatecontent); $result .= str_ireplace($patterns, $replacements, $templatecontent);
return $result; return $result;
} }
/**
* Return the input form html from a specific field.
*
* @param stdClass $processeddata the previous process data information.
* @param int|null $entryid the possible entry id
* @param stdClass|null $entrydata the entry data from a previous form or from a real entry
* @param data_field_base $field the field object
* @return string the add entry HTML content
*/
private function get_field_input(
stdClass $processeddata,
?int $entryid = null,
?stdClass $entrydata = null,
data_field_base $field
): string {
$renderer = $this->manager->get_renderer();
$errors = '';
$fieldnotifications = $processeddata->fieldnotifications[$field->field->name] ?? [];
if (!empty($fieldnotifications)) {
foreach ($fieldnotifications as $notification) {
$errors .= $renderer->notification($notification);
}
}
$fielddisplay = '';
if ($field->type === 'unknown') {
if ($this->canmanageentries) { // Display notification for users that can manage entries.
$errors .= $renderer->notification(get_string(
'missingfieldtype',
'data',
(object)['name' => $field->field->name]
));
}
} else {
$fielddisplay = $field->display_add_field($entryid, $entrydata);
}
return $errors . $fielddisplay;
}
} }

View File

@ -178,7 +178,6 @@ $string['fieldenclosure'] = 'Field enclosure';
$string['fieldheight'] = 'Height'; $string['fieldheight'] = 'Height';
$string['fieldheightlistview'] = 'Height (in pixels) in list view'; $string['fieldheightlistview'] = 'Height (in pixels) in list view';
$string['fieldheightsingleview'] = 'Height (in pixels) in single view'; $string['fieldheightsingleview'] = 'Height (in pixels) in single view';
$string['fieldids'] = 'Field ids';
$string['fieldmappings'] = 'Field mappings'; $string['fieldmappings'] = 'Field mappings';
$string['fieldmappings_help'] = 'This menu allows you to keep the data from the existing database. To preserve the data in a field, you must map it to a new field, where the data will appear. Any field can also be left blank, with no information copied into it. Any old field not mapped to a new one will be lost and all its data removed. $string['fieldmappings_help'] = 'This menu allows you to keep the data from the existing database. To preserve the data in a field, you must map it to a new field, where the data will appear. Any field can also be left blank, with no information copied into it. Any old field not mapped to a new one will be lost and all its data removed.
You can only map fields of the same type, so each drop-down menu will have different fields in it. Also, you must be careful not to try and map one old field to more than one new field.'; You can only map fields of the same type, so each drop-down menu will have different fields in it. Also, you must be careful not to try and map one old field to more than one new field.';
@ -188,7 +187,11 @@ $string['fieldnotmatched'] = 'The following fields in your file are not known in
$string['fieldoptions'] = 'Options (one per line)'; $string['fieldoptions'] = 'Options (one per line)';
$string['fields'] = 'Fields'; $string['fields'] = 'Fields';
$string['fieldshelp'] = 'Create fields to collect different types of data. Fields define the structure of the entries in your database.'; $string['fieldshelp'] = 'Create fields to collect different types of data. Fields define the structure of the entries in your database.';
$string['fieldsinformationtags'] = 'Field information';
$string['fieldsnavigation'] = 'Fields tertiary navigation'; $string['fieldsnavigation'] = 'Fields tertiary navigation';
$string['fieldtagdescription'] = '{$a} description';
$string['fieldtagname'] = '{$a} name';
$string['fieldtagid'] = '{$a} id';
$string['fieldupdated'] = 'Field updated'; $string['fieldupdated'] = 'Field updated';
$string['fieldwidth'] = 'Width'; $string['fieldwidth'] = 'Width';
$string['fieldwidthlistview'] = 'Width (in pixels) in list view'; $string['fieldwidthlistview'] = 'Width (in pixels) in list view';
@ -336,6 +339,7 @@ $string['openafterclose'] = 'You have specified an open date after the close dat
$string['optionaldescription'] = 'Short description (optional)'; $string['optionaldescription'] = 'Short description (optional)';
$string['optionalfilename'] = 'Filename (optional)'; $string['optionalfilename'] = 'Filename (optional)';
$string['other'] = 'Other'; $string['other'] = 'Other';
$string['otherfields'] = 'All other fields';
$string['overwrite'] = 'Overwrite'; $string['overwrite'] = 'Overwrite';
$string['overrwritedesc'] = 'Replace existing preset with this name and overwrite its contents'; $string['overrwritedesc'] = 'Replace existing preset with this name and overwrite its contents';
$string['overwritesettings'] = 'Overwrite current settings such as comments, ratings, etc.'; $string['overwritesettings'] = 'Overwrite current settings such as comments, ratings, etc.';
@ -484,3 +488,6 @@ $string['savetemplate'] = 'Save template';
$string['addedby'] = 'Added by'; $string['addedby'] = 'Added by';
$string['addentries'] = 'Add entries'; $string['addentries'] = 'Add entries';
$string['todatabase'] = 'to this database.'; $string['todatabase'] = 'to this database.';
// Deprecated since Moodle 4.2.
$string['fieldids'] = 'Field ids';

View File

@ -8,4 +8,4 @@ savetemplate,mod_data
addedby,mod_data addedby,mod_data
addentries,mod_data addentries,mod_data
todatabase,mod_data todatabase,mod_data
fieldids,mod_data

View File

@ -826,34 +826,35 @@ function data_generate_tag_form($recordid = false, $selected = []) {
function data_replace_field_in_templates($data, $searchfieldname, $newfieldname) { function data_replace_field_in_templates($data, $searchfieldname, $newfieldname) {
global $DB; global $DB;
if (!empty($newfieldname)) { $newdata = (object)['id' => $data->id];
$prestring = '[['; $update = false;
$poststring = ']]'; $templates = ['listtemplate', 'singletemplate', 'asearchtemplate', 'addtemplate', 'rsstemplate'];
$idpart = '#id'; foreach ($templates as $templatename) {
if (empty($data->$templatename)) {
} else { continue;
$prestring = ''; }
$poststring = ''; $search = [
$idpart = ''; '[[' . $searchfieldname . ']]',
'[[' . $searchfieldname . '#id]]',
'[[' . $searchfieldname . '#name]]',
'[[' . $searchfieldname . '#description]]',
];
if (empty($newfieldname)) {
$replace = ['', '', '', ''];
} else {
$replace = [
'[[' . $newfieldname . ']]',
'[[' . $newfieldname . '#id]]',
'[[' . $newfieldname . '#name]]',
'[[' . $newfieldname . '#description]]',
];
}
$newdata->{$templatename} = str_ireplace($search, $replace, $data->{$templatename} ?? '');
$update = true;
}
if (!$update) {
return true;
} }
$newdata = new stdClass();
$newdata->id = $data->id;
$newdata->singletemplate = str_ireplace('[['.$searchfieldname.']]',
$prestring.$newfieldname.$poststring, $data->singletemplate ?? '');
$newdata->listtemplate = str_ireplace('[['.$searchfieldname.']]',
$prestring.$newfieldname.$poststring, $data->listtemplate ?? '');
$newdata->addtemplate = str_ireplace('[['.$searchfieldname.']]',
$prestring.$newfieldname.$poststring, $data->addtemplate ?? '');
$newdata->addtemplate = str_ireplace('[['.$searchfieldname.'#id]]',
$prestring.$newfieldname.$idpart.$poststring, $data->addtemplate ?? '');
$newdata->rsstemplate = str_ireplace('[['.$searchfieldname.']]',
$prestring.$newfieldname.$poststring, $data->rsstemplate ?? '');
return $DB->update_record('data', $newdata); return $DB->update_record('data', $newdata);
} }
@ -864,29 +865,36 @@ function data_replace_field_in_templates($data, $searchfieldname, $newfieldname)
* @global object * @global object
* @param object $data * @param object $data
* @param string $newfieldname * @param string $newfieldname
* @return bool if the field has been added or not
*/ */
function data_append_new_field_to_templates($data, $newfieldname) { function data_append_new_field_to_templates($data, $newfieldname): bool {
global $DB; global $DB, $OUTPUT;
$newdata = new stdClass(); $newdata = (object)['id' => $data->id];
$newdata->id = $data->id; $update = false;
$change = false; $templates = ['singletemplate', 'addtemplate', 'rsstemplate'];
foreach ($templates as $templatename) {
if (!empty($data->singletemplate)) { if (empty($data->$templatename)
$newdata->singletemplate = $data->singletemplate.' [[' . $newfieldname .']]'; || strpos($data->$templatename, "[[$newfieldname]]") !== false
$change = true; || strpos($data->$templatename, "##otherfields##") !== false
) {
continue;
}
$newdata->$templatename = $data->$templatename;
$fields = [[
'fieldname' => '[[' . $newfieldname . '#name]]',
'fieldcontent' => '[[' . $newfieldname . ']]',
]];
$newdata->$templatename .= $OUTPUT->render_from_template(
'mod_data/fields_otherfields',
['fields' => $fields, 'classes' => 'added_field']
);
$update = true;
} }
if (!empty($data->addtemplate)) { if (!$update) {
$newdata->addtemplate = $data->addtemplate.' [[' . $newfieldname . ']]'; return false;
$change = true;
}
if (!empty($data->rsstemplate)) {
$newdata->rsstemplate = $data->singletemplate.' [[' . $newfieldname . ']]';
$change = true;
}
if ($change) {
$DB->update_record('data', $newdata);
} }
return $DB->update_record('data', $newdata);
} }
@ -1673,7 +1681,7 @@ function mod_data_rating_can_see_item_ratings($params) {
* @return void * @return void
*/ */
function data_print_preference_form($data, $perpage, $search, $sort='', $order='ASC', $search_array = '', $advanced = 0, $mode= ''){ function data_print_preference_form($data, $perpage, $search, $sort='', $order='ASC', $search_array = '', $advanced = 0, $mode= ''){
global $CFG, $DB, $PAGE, $OUTPUT; global $DB, $PAGE, $OUTPUT;
$cm = get_coursemodule_from_instance('data', $data->id); $cm = get_coursemodule_from_instance('data', $data->id);
$context = context_module::instance($cm->id); $context = context_module::instance($cm->id);
@ -1802,21 +1810,45 @@ function data_print_preference_form($data, $perpage, $search, $sort='', $order='
$replacement = array(); $replacement = array();
// Then we generate strings to replace for normal tags // Then we generate strings to replace for normal tags
$otherfields = [];
foreach ($fields as $field) { foreach ($fields as $field) {
$fieldname = $field->field->name; $fieldname = $field->field->name;
$fieldname = preg_quote($fieldname, '/'); $fieldname = preg_quote($fieldname, '/');
$patterns[] = "/\[\[$fieldname\]\]/i";
$searchfield = data_get_field_from_id($field->field->id, $data); $searchfield = data_get_field_from_id($field->field->id, $data);
if ($searchfield->type === 'unknown') { if ($searchfield->type === 'unknown') {
continue; continue;
} }
if (!empty($search_array[$field->field->id]->data)) { if (!empty($search_array[$field->field->id]->data)) {
$replacement[] = $searchfield->display_search_field($search_array[$field->field->id]->data); $searchinput = $searchfield->display_search_field($search_array[$field->field->id]->data);
} else { } else {
$replacement[] = $searchfield->display_search_field(); $searchinput = $searchfield->display_search_field();
}
$patterns[] = "/\[\[$fieldname\]\]/i";
$replacement[] = $searchinput;
// Extra field information.
$patterns[] = "/\[\[$fieldname#name\]\]/i";
$replacement[] = $field->field->name;
$patterns[] = "/\[\[$fieldname#description\]\]/i";
$replacement[] = $field->field->description;
// Other fields.
if (strpos($asearchtemplate, "[[" . $field->field->name . "]]") === false) {
$otherfields[] = [
'fieldname' => $searchfield->field->name,
'fieldcontent' => $searchinput,
];
} }
} }
$patterns[] = "/##otherfields##/";
if (!empty($otherfields)) {
$replacement[] = $OUTPUT->render_from_template(
'mod_data/fields_otherfields',
['fields' => $otherfields]
);
} else {
$replacement[] = '';
}
$fn = !empty($search_array[DATA_FIRSTNAME]->data) ? $search_array[DATA_FIRSTNAME]->data : ''; $fn = !empty($search_array[DATA_FIRSTNAME]->data) ? $search_array[DATA_FIRSTNAME]->data : '';
$ln = !empty($search_array[DATA_LASTNAME]->data) ? $search_array[DATA_LASTNAME]->data : ''; $ln = !empty($search_array[DATA_LASTNAME]->data) ? $search_array[DATA_LASTNAME]->data : '';
$patterns[] = '/##firstname##/'; $patterns[] = '/##firstname##/';

View File

@ -1,14 +1,15 @@
<div class="imagegallery-addentry"> <div class="imagegallery-addentry">
<div class="form-group"> <div class="form-group">
<div class="font-weight-bold">Title</div> <div class="font-weight-bold">[[title#name]]</div>
[[title]] [[title]]
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="font-weight-bold">Image</div> <div class="font-weight-bold">[[image#name]]</div>
[[image]] [[image]]
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="font-weight-bold">Description</div> <div class="font-weight-bold">[[description#name]]</div>
[[description]] [[description]]
</div> </div>
##otherfields##
</div> </div>

View File

@ -10,11 +10,11 @@
</div> </div>
<div class="form-group col"> <div class="form-group col">
<div class="font-weight-bold mb-2">Title</div> <div class="font-weight-bold mb-2">[[title#name]]</div>
[[title]] [[title]]
</div> </div>
<div class="form-group col"> <div class="form-group col">
<div class="font-weight-bold mb-2">Description</div> <div class="font-weight-bold mb-2">[[description#name]]</div>
[[description]] [[description]]
</div> </div>
</div> </div>

View File

@ -27,5 +27,6 @@
<div class="row singleentry-image"> <div class="row singleentry-image">
<div class="col">[[image]]</div> <div class="col">[[image]]</div>
</div> </div>
##otherfields##
</div> </div>
</div> </div>

View File

@ -90,3 +90,29 @@ Feature: Users can use the Image gallery preset
And I press "Save" And I press "Save"
Then I should see "New image" Then I should see "New image"
And I should see "This is the description for the new image." And I should see "This is the description for the new image."
@javascript
Scenario: Image gallery. Renaming a field should affect the template
Given I am on the "Mountain landscapes" "data activity" page logged in as teacher1
And I navigate to "Fields" in current page administration
And I open the action menu in "title" "table_row"
And I choose "Edit" in the open action menu
And I set the field "Field name" to "Edited field name"
And I press "Save"
And I should see "Field updated"
When I navigate to "Database" in current page administration
Then I click on "Advanced search" "checkbox"
And I should see "Edited field name"
And I click on "Add entry" "button"
And I should see "Edited field name"
@javascript
Scenario: Image gallery. Has otherfields tag
Given the following "mod_data > fields" exist:
| database | type | name | description |
| data1 | text | Extra field | Test field description |
And I am on the "Mountain landscapes" "data activity" page logged in as teacher1
When I select "Single view" from the "jump" singleselect
Then I should see "Extra field"
And I click on "Add entry" "button"
And I should see "Extra field"

View File

@ -1,10 +1,11 @@
<div class="journal-addentry"> <div class="journal-addentry">
<div class="form-group"> <div class="form-group">
<div class="font-weight-bold">Title</div> <div class="font-weight-bold">[[Title#name]]</div>
[[Title]] [[Title]]
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="font-weight-bold">Content</div> <div class="font-weight-bold">[[Content#name]]</div>
[[Content]] [[Content]]
</div> </div>
##otherfields##
</div> </div>

View File

@ -10,12 +10,12 @@
</div> </div>
<div class="form-group col"> <div class="form-group col">
<div class="font-weight-bold mb-2">Title</div> <div class="font-weight-bold mb-2">[[Title#name]]</div>
[[title]] [[Title]]
</div> </div>
<div class="form-group col"> <div class="form-group col">
<div class="font-weight-bold mb-2">Content</div> <div class="font-weight-bold mb-2">[[Content#name]]</div>
[[content]] [[Content]]
</div> </div>
</div> </div>
</div> </div>

View File

@ -24,5 +24,6 @@
<div class="singleentry-content"> <div class="singleentry-content">
[[Content]] [[Content]]
</div> </div>
##otherfields##
</div> </div>
</div> </div>

View File

@ -76,3 +76,27 @@ Feature: Users can use the Journal preset
And I press "Save" And I press "Save"
Then I should see "This is the title" Then I should see "This is the title"
And I should see "This is the content for the new entry." And I should see "This is the content for the new entry."
@javascript
Scenario: Journal. Renaming a field should affect the template
Given I am on the "Student reflections" "data activity" page logged in as teacher1
And I navigate to "Fields" in current page administration
And I open the action menu in "Content" "table_row"
And I choose "Edit" in the open action menu
And I set the field "Field name" to "Edited field name"
And I press "Save"
And I should see "Field updated"
When I navigate to "Database" in current page administration
Then I click on "Advanced search" "checkbox"
And I should see "Edited field name"
And I click on "Add entry" "button"
And I should see "Edited field name"
@javascript
Scenario: Journal. Has otherfields tag
Given the following "mod_data > fields" exist:
| database | type | name | description |
| data1 | text | Extra field | Test field description |
And I am on the "Student reflections" "data activity" page logged in as teacher1
When I click on "Add entry" "button"
Then I should see "Extra field"

View File

@ -1,18 +1,19 @@
<div class="proposals-addentry"> <div class="proposals-addentry">
<div class="form-group"> <div class="form-group">
<div class="font-weight-bold">Title</div> <div class="font-weight-bold">[[Title#name]]</div>
[[Title]] [[Title]]
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="font-weight-bold">Status</div> <div class="font-weight-bold">[[Status#name]]</div>
[[Status]] [[Status]]
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="font-weight-bold">Summary</div> <div class="font-weight-bold">[[Summary#name]]</div>
[[Summary]] [[Summary]]
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="font-weight-bold">Content</div> <div class="font-weight-bold">[[Content#name]]</div>
[[Content]] [[Content]]
</div> </div>
##otherfields##
</div> </div>

View File

@ -10,19 +10,19 @@
</div> </div>
<div class="form-group col"> <div class="form-group col">
<div class="font-weight-bold mb-2">Title</div> <div class="font-weight-bold mb-2">[[Title#name]]</div>
[[Title]] [[Title]]
</div> </div>
<div class="form-group col"> <div class="form-group col">
<div class="font-weight-bold mb-2">Status</div> <div class="font-weight-bold mb-2">[[Status#name]]</div>
[[Status]] [[Status]]
</div> </div>
<div class="form-group col"> <div class="form-group col">
<div class="font-weight-bold mb-2">Summary</div> <div class="font-weight-bold mb-2">[[Summary#name]]</div>
[[Summary]] [[Summary]]
</div> </div>
<div class="form-group col"> <div class="form-group col">
<div class="font-weight-bold mb-2">Content</div> <div class="font-weight-bold mb-2">[[Content#name]]</div>
[[Content]] [[Content]]
</div> </div>
</div> </div>

View File

@ -21,18 +21,18 @@
<div class="proposals-single-body"> <div class="proposals-single-body">
<div class="row my-3"> <div class="row my-3">
<div class="col-3 col-md-1"><strong>Status</strong></div> <div class="col-3 col-md-1"><strong>[[Status#name]]</strong></div>
<div class="col">[[Status]]</div> <div class="col">[[Status]]</div>
</div> </div>
<div class="row singleentry-summary"> <div class="row singleentry-summary">
<div class="col"> <div class="col">
<h3 class="my-5">Summary</h3> <h3 class="my-5">[[Summary#name]]</h3>
[[Summary]] [[Summary]]
</div> </div>
</div> </div>
<div class="row singleentry-content"> <div class="row singleentry-content">
<div class="col"> <div class="col">
<h3 class="my-5">Content</h3> <h3 class="my-5">[[Content#name]]</h3>
[[Content]] [[Content]]
</div> </div>
</div> </div>

View File

@ -23,21 +23,22 @@
<div class="proposals-single-body"> <div class="proposals-single-body">
<div class="row singleentry-status"> <div class="row singleentry-status">
<div class="col"> <div class="col">
<h3 class="my-5">Status</h3> <h3 class="my-5">[[Status#name]]</h3>
[[Status]] [[Status]]
</div> </div>
</div> </div>
<div class="row singleentry-summary"> <div class="row singleentry-summary">
<div class="col"> <div class="col">
<h3 class="my-5">Summary</h3> <h3 class="my-5">[[Summary#name]]</h3>
[[Summary]] [[Summary]]
</div> </div>
</div> </div>
<div class="row singleentry-content"> <div class="row singleentry-content">
<div class="col"> <div class="col">
<h3 class="my-5">Content</h3> <h3 class="my-5">[[Content#name]]</h3>
[[Content]] [[Content]]
</div> </div>
</div> </div>
##otherfields##
</div> </div>
</div> </div>

View File

@ -94,3 +94,31 @@ Feature: Users can use the Proposals preset
And I should see "Approved" And I should see "Approved"
And I should see "This is the summary for the new entry." And I should see "This is the summary for the new entry."
And I should see "This is the content for the new entry." And I should see "This is the content for the new entry."
@javascript
Scenario: Proposals. Renaming a field should affect the template
Given I am on the "Student projects" "data activity" page logged in as teacher1
And I navigate to "Fields" in current page administration
And I open the action menu in "Summary" "table_row"
And I choose "Edit" in the open action menu
And I set the field "Field name" to "Edited field name"
And I press "Save"
And I should see "Field updated"
When I navigate to "Database" in current page administration
Then I click on "Advanced search" "checkbox"
And I should see "Edited field name"
And I select "Single view" from the "jump" singleselect
And I should see "Edited field name"
And I click on "Add entry" "button"
And I should see "Edited field name"
@javascript
Scenario: Proposals. Has otherfields tag
Given the following "mod_data > fields" exist:
| database | type | name | description |
| data1 | text | Extra field | Test field description |
And I am on the "Student projects" "data activity" page logged in as teacher1
When I select "Single view" from the "jump" singleselect
Then I should see "Extra field"
And I click on "Add entry" "button"
And I should see "Extra field"

View File

@ -1,6 +1,6 @@
<div class="resources-addentry"> <div class="resources-addentry">
<div class="form-group"> <div class="form-group">
<div class="font-weight-bold">Title</div> <div class="font-weight-bold">[[Title#name]]</div>
[[Title]] [[Title]]
</div> </div>
<div class="form-group"> <div class="form-group">
@ -8,7 +8,7 @@
[[Author]] [[Author]]
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="font-weight-bold">Cover</div> <div class="font-weight-bold">[[Cover#name]]</div>
[[Cover]] [[Cover]]
</div> </div>
<div class="form-group"> <div class="form-group">
@ -16,11 +16,12 @@
[[Description]] [[Description]]
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="font-weight-bold">Web link</div> <div class="font-weight-bold">[[Web link#name]]</div>
[[Web link]] [[Web link]]
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="font-weight-bold">Type</div> <div class="font-weight-bold">[[Type#name]]</div>
[[Type]] [[Type]]
</div> </div>
##otherfields##
</div> </div>

View File

@ -10,7 +10,7 @@
</div> </div>
<div class="form-group col"> <div class="form-group col">
<div class="font-weight-bold mb-2">Title</div> <div class="font-weight-bold mb-2">[[Title#name]]</div>
[[Title]] [[Title]]
</div> </div>
<div class="form-group col"> <div class="form-group col">
@ -22,11 +22,11 @@
[[Description]] [[Description]]
</div> </div>
<div class="form-group col"> <div class="form-group col">
<div class="font-weight-bold mb-2">Link</div> <div class="font-weight-bold mb-2">[[Web link#name]]</div>
[[Web link]] [[Web link]]
</div> </div>
<div class="form-group col"> <div class="form-group col">
<div class="font-weight-bold mb-2">Type</div> <div class="font-weight-bold mb-2">[[Type#name]]</div>
[[Type]] [[Type]]
</div> </div>
</div> </div>

View File

@ -27,7 +27,7 @@
<div class="col-9 col-md-11">[[Author]]</div> <div class="col-9 col-md-11">[[Author]]</div>
</div> </div>
<div class="row my-3"> <div class="row my-3">
<div class="col-3 col-md-1"><strong>Type</strong></div> <div class="col-3 col-md-1"><strong>[[Type#name]]</strong></div>
<div class="col-9 col-md-11">[[Type]]</div> <div class="col-9 col-md-11">[[Type]]</div>
</div> </div>
<div class="row my-3"> <div class="row my-3">

View File

@ -28,7 +28,7 @@
<div class="col-9 col-md-auto">[[Author]]</div> <div class="col-9 col-md-auto">[[Author]]</div>
</div> </div>
<div class="row my-3"> <div class="row my-3">
<div class="col-3 col-md-2 font-weight-bold">Type</div> <div class="col-3 col-md-2 font-weight-bold">[[Type#name]]</div>
<div class="col-9 col-md-auto">[[Type]]</div> <div class="col-9 col-md-auto">[[Type]]</div>
</div> </div>
<div class="row my-3"> <div class="row my-3">
@ -45,5 +45,6 @@
[[Description]] [[Description]]
</div> </div>
</div> </div>
##otherfields##
</div> </div>
</div> </div>

View File

@ -99,3 +99,29 @@ Feature: Users can use the Resources preset
And I should see "This is the author" And I should see "This is the author"
And I should see "https://thisisthelink.cat" And I should see "https://thisisthelink.cat"
And I should see "Type2" And I should see "Type2"
@javascript
Scenario: Resources. Renaming a field should affect the template
Given I am on the "Student resources" "data activity" page logged in as teacher1
And I navigate to "Fields" in current page administration
And I open the action menu in "Type" "table_row"
And I choose "Edit" in the open action menu
And I set the field "Field name" to "Edited field name"
And I press "Save"
And I should see "Field updated"
When I navigate to "Database" in current page administration
Then I click on "Advanced search" "checkbox"
And I should see "Edited field name"
And I click on "Add entry" "button"
And I should see "Edited field name"
@javascript
Scenario: Resources. Has otherfields tag
Given the following "mod_data > fields" exist:
| database | type | name | description |
| data1 | text | Extra field | Test field description |
And I am on the "Student resources" "data activity" page logged in as teacher1
When I select "Single view" from the "jump" singleselect
Then I should see "Extra field"
And I click on "Add entry" "button"
And I should see "Extra field"

View File

@ -40,6 +40,7 @@
{{{fieldcontent}}} {{{fieldcontent}}}
</div> </div>
{{/fields}} {{/fields}}
##otherfields##
{{#tags}} {{#tags}}
<div class="form-group pt-3"> <div class="form-group pt-3">
<div class="font-weight-bold">{{#str}}tags{{/str}}</div> <div class="font-weight-bold">{{#str}}tags{{/str}}</div>

View File

@ -61,6 +61,7 @@
<p class="mt-2">{{fieldcontent}}</p> <p class="mt-2">{{fieldcontent}}</p>
</div> </div>
{{/fields}} {{/fields}}
##otherfields##
{{#tags}} {{#tags}}
<div class="mt-4"> <div class="mt-4">
<span class="font-weight-bold">{{#str}}tags{{/str}}</span> <span class="font-weight-bold">{{#str}}tags{{/str}}</span>

View File

@ -0,0 +1,33 @@
{{!
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 mod_data/fields_otherfields
The ##otherfields## template.
Example context (json):
{
"fieldname": "This is the field name",
"fieldcontent": "This is the field name",
"classes": "added_fields"
}
}}
<div class="{{^classes}}tag_otherfields{{/classes}} {{#classes}}{{classes}}{{/classes}}">
{{#fields}}
<div class="mt-4">
<span class="font-weight-bold">{{fieldname}}</span>
<p class="mt-2">{{{fieldcontent}}}</p>
</div>
{{/fields}}
</div>

View File

@ -0,0 +1,82 @@
@mod @mod_data
Feature: Database entries can be searched using an advanced search form.
In order to find an entry
As a user
I need to have an advanced search form
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@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 |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| data | Test database name | n | C1 | data1 |
And the following "mod_data > fields" exist:
| database | type | name | description |
| data1 | text | My Field | Field 1 description |
| data1 | text | Their field | Field 2 description |
And the following "mod_data > entries" exist:
| database | user | My Field | Their field |
| data1 | teacher1 | First content | Owned content |
| data1 | teacher1 | Second content | Authored content |
And I am on the "Test database name" "data activity" page logged in as teacher1
And I should see "First content"
And I should see "Second content"
@javascript
Scenario: Content can be searched using advanced search
Given I click on "Advanced search" "checkbox"
And I should see "My Field" in the "data_adv_form" "region"
And I should see "Their field" in the "data_adv_form" "region"
When I set the field "My Field" to "First"
And I click on "Save settings" "button" in the "data_adv_form" "region"
Then I should see "First content"
And I should not see "Second content"
@javascript
Scenario: Advanced search template can use field information tags
Given I navigate to "Templates" in current page administration
And I set the field "Templates tertiary navigation" to "Advanced search template"
And I set the following fields to these values:
| Advanced search template | The test is on [[My Field#name]], [[My Field#description]], and the input [[My Field]] |
And I click on "Save" "button" in the "sticky-footer" "region"
And I navigate to "Database" in current page administration
And I should see "First content"
And I should see "Second content"
And I click on "Advanced search" "checkbox"
And I should see "The test is on My Field, Field 1 description, and the input" in the "data_adv_form" "region"
And I should not see "Their field" in the "data_adv_form" "region"
When I set the field "My Field" to "First"
And I click on "Save settings" "button" in the "data_adv_form" "region"
Then I should see "First content"
And I should not see "Second content"
@javascript
Scenario: Advanced search can use otherfields tag
Given I navigate to "Templates" in current page administration
And I set the field "Templates tertiary navigation" to "Advanced search template"
And I set the following fields to these values:
| Advanced search template | Main search [[My Field]], Other fields ##otherfields## |
And I click on "Save" "button" in the "sticky-footer" "region"
And I navigate to "Database" in current page administration
And I should see "First content"
And I should see "Second content"
And I click on "Advanced search" "checkbox"
And I should see "Main search" in the "data_adv_form" "region"
And I should see "Other fields" in the "data_adv_form" "region"
And I should see "Their field" in the "data_adv_form" "region"
When I set the field "My Field" to "First"
And I click on "Save settings" "button" in the "data_adv_form" "region"
Then I should see "First content"
And I should not see "Second content"
And I set the field "My Field" to ""
And I set the field "Their field" to "Authored content"
And I click on "Save settings" "button" in the "data_adv_form" "region"
And I should not see "First content"
And I should see "Second content"

View File

@ -2039,4 +2039,130 @@ class lib_test extends \advanced_testcase {
$this->assertNotEmpty($activity->{$template}); $this->assertNotEmpty($activity->{$template});
} }
} }
/**
* Test for data_replace_field_in_templates().
*
* @covers ::data_replace_field_in_templates
*/
public function test_data_replace_field_in_templates(): void {
global $DB;
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$templatecontent = "Field [[myfield]], [[myfield#id]], [[myfield#name]], [[myfield#description]], ";
$params = ['course' => $course];
foreach (manager::TEMPLATES_LIST as $templatename => $templatefile) {
$params[$templatename] = $templatecontent;
}
$activity = $this->getDataGenerator()->create_module(manager::MODULE, $params);
$generator = $this->getDataGenerator()->get_plugin_generator(manager::PLUGINNAME);
$fieldrecord = (object)['name' => 'myfield', 'type' => 'text', 'description' => 'This is a field'];
$generator->create_field($fieldrecord, $activity);
data_replace_field_in_templates($activity, 'myfield', 'newfieldname');
$dbactivity = $DB->get_record(manager::MODULE, ['id' => $activity->id]);
$newcontent = "Field [[newfieldname]], [[newfieldname#id]], [[newfieldname#name]], [[newfieldname#description]], ";
// Field compatible templates.
$this->assertEquals($newcontent, $dbactivity->listtemplate);
$this->assertEquals($newcontent, $dbactivity->singletemplate);
$this->assertEquals($newcontent, $dbactivity->asearchtemplate);
$this->assertEquals($newcontent, $dbactivity->addtemplate);
$this->assertEquals($newcontent, $dbactivity->rsstemplate);
// Other templates.
$this->assertEquals($templatecontent, $dbactivity->listtemplateheader);
$this->assertEquals($templatecontent, $dbactivity->listtemplatefooter);
$this->assertEquals($templatecontent, $dbactivity->csstemplate);
$this->assertEquals($templatecontent, $dbactivity->jstemplate);
$this->assertEquals($templatecontent, $dbactivity->rsstitletemplate);
}
/**
* Test for data_append_new_field_to_templates().
*
* @covers ::data_append_new_field_to_templates
* @dataProvider data_append_new_field_to_templates_provider
* @param bool $hasfield if the field is present in the templates
* @param bool $hasotherfields if the field is not present in the templates
* @param bool $expected the expected return
*/
public function test_data_append_new_field_to_templates(bool $hasfield, bool $hasotherfields, bool $expected) {
global $DB;
$this->resetAfterTest();
$this->setAdminUser();
$templatecontent = "Template content";
if ($hasfield) {
$templatecontent .= "Has [[myfield]].";
}
if ($hasotherfields) {
$templatecontent .= "And also ##otherfields##.";
}
$course = $this->getDataGenerator()->create_course();
$params = ['course' => $course];
foreach (manager::TEMPLATES_LIST as $templatename => $templatefile) {
$params[$templatename] = $templatecontent;
}
$activity = $this->getDataGenerator()->create_module(manager::MODULE, $params);
$result = data_append_new_field_to_templates($activity, 'myfield');
$this->assertEquals($expected, $result);
// Check fields with auto add fields.
$dbactivity = $DB->get_record(manager::MODULE, ['id' => $activity->id]);
if ($hasfield || $hasotherfields) {
$this->assertEquals($dbactivity->singletemplate, $templatecontent);
$this->assertEquals($dbactivity->addtemplate, $templatecontent);
$this->assertEquals($dbactivity->rsstemplate, $templatecontent);
} else {
$regexp = '|Template content.*\[\[myfield\]\]|';
// We don't want line breaks for the validations.
$this->assertMatchesRegularExpression($regexp, str_replace("\n", '', $dbactivity->singletemplate));
$this->assertMatchesRegularExpression($regexp, str_replace("\n", '', $dbactivity->addtemplate));
$this->assertMatchesRegularExpression($regexp, str_replace("\n", '', $dbactivity->rsstemplate));
}
// No auto add field templates.
$this->assertEquals($dbactivity->asearchtemplate, $templatecontent);
$this->assertEquals($dbactivity->listtemplate, $templatecontent);
$this->assertEquals($dbactivity->listtemplateheader, $templatecontent);
$this->assertEquals($dbactivity->listtemplatefooter, $templatecontent);
$this->assertEquals($dbactivity->csstemplate, $templatecontent);
$this->assertEquals($dbactivity->jstemplate, $templatecontent);
$this->assertEquals($dbactivity->rsstitletemplate, $templatecontent);
}
/**
* Data provider for test_data_append_new_field_to_templates().
*
* @return array of scenarios
*/
public function data_append_new_field_to_templates_provider(): array {
return [
'Plain template' => [
'hasfield' => false,
'hasotherfields' => false,
'expected' => true,
],
'Field already present' => [
'hasfield' => true,
'hasotherfields' => false,
'expected' => false,
],
'##otherfields## tag present' => [
'hasfield' => false,
'hasotherfields' => true,
'expected' => false,
],
'Field already present and ##otherfields## tag present' => [
'hasfield' => true,
'hasotherfields' => true,
'expected' => false,
],
];
}
} }

View File

@ -97,17 +97,19 @@ class template_test extends \advanced_testcase {
// Generate an entry. // Generate an entry.
$generator = $this->getDataGenerator()->get_plugin_generator('mod_data'); $generator = $this->getDataGenerator()->get_plugin_generator('mod_data');
$fieldrecord = (object)[ $fieldrecord = (object)['name' => 'myfield', 'type' => 'text'];
'name' => 'myfield',
'type' => 'text',
];
$field = $generator->create_field($fieldrecord, $activity); $field = $generator->create_field($fieldrecord, $activity);
$otherfieldrecord = (object)['name' => 'otherfield', 'type' => 'text'];
$otherfield = $generator->create_field($otherfieldrecord, $activity);
$this->setUser($user); $this->setUser($user);
$entryid = $generator->create_entry( $entryid = $generator->create_entry(
$activity, $activity,
[$field->field->id => 'Example entry'], [
$field->field->id => 'Example entry',
$otherfield->field->id => 'Another example',
],
0, 0,
['Cats', 'Dogs'], ['Cats', 'Dogs'],
['approved' => $approved] ['approved' => $approved]
@ -149,6 +151,8 @@ class template_test extends \advanced_testcase {
'{timeadded}' => userdate($entry->timecreated, get_string('strftimedatemonthabbr', 'langconfig')), '{timeadded}' => userdate($entry->timecreated, get_string('strftimedatemonthabbr', 'langconfig')),
'{timemodified}' => userdate($entry->timemodified, get_string('strftimedatemonthabbr', 'langconfig')), '{timemodified}' => userdate($entry->timemodified, get_string('strftimedatemonthabbr', 'langconfig')),
'{fieldid}' => $field->field->id, '{fieldid}' => $field->field->id,
'{fieldname}' => $field->field->name,
'{fielddescription}' => $field->field->description,
'{entryid}' => $entry->id, '{entryid}' => $entry->id,
'{cmid}' => $cm->id, '{cmid}' => $cm->id,
'{courseid}' => $course->id, '{courseid}' => $course->id,
@ -330,11 +334,21 @@ class template_test extends \advanced_testcase {
'expected' => '|Some .*Example entry.* tag|', 'expected' => '|Some .*Example entry.* tag|',
'rolename' => 'editingteacher', 'rolename' => 'editingteacher',
], ],
'Teacher field#id name tag' => [ 'Teacher field#id tag' => [
'templatecontent' => 'Some [[myfield#id]] tag', 'templatecontent' => 'Some [[myfield#id]] tag',
'expected' => '|Some {fieldid} tag|', 'expected' => '|Some {fieldid} tag|',
'rolename' => 'editingteacher', 'rolename' => 'editingteacher',
], ],
'Teacher field#name tag' => [
'templatecontent' => 'Some [[myfield#name]] tag',
'expected' => '|Some {fieldname} tag|',
'rolename' => 'editingteacher',
],
'Teacher field#description tag' => [
'templatecontent' => 'Some [[myfield#description]] tag',
'expected' => '|Some {fielddescription} tag|',
'rolename' => 'editingteacher',
],
'Teacher comments name tag with comments enabled' => [ 'Teacher comments name tag with comments enabled' => [
'templatecontent' => 'Some ##comments## tag', 'templatecontent' => 'Some ##comments## tag',
'expected' => '|Some .*Comments.* tag|', 'expected' => '|Some .*Comments.* tag|',
@ -434,6 +448,16 @@ class template_test extends \advanced_testcase {
'enableratings' => false, 'enableratings' => false,
'options' => ['showmore' => true], 'options' => ['showmore' => true],
], ],
'Teacher otherfields tag' => [
'templatecontent' => 'Some ##otherfields## tag',
'expected' => '|Some .*{fieldname}.*Example entry.*otherfield.*Another example.* tag|',
'rolename' => 'editingteacher',
],
'Teacher otherfields tag with some field in the template' => [
'templatecontent' => 'Some [[myfield]] and ##otherfields## tag',
'expected' => '|Some .*Example entry.* and .*otherfield.*Another example.* tag|',
'rolename' => 'editingteacher',
],
// Student scenarios. // Student scenarios.
'Student id tag' => [ 'Student id tag' => [
'templatecontent' => 'Some ##id## tag', 'templatecontent' => 'Some ##id## tag',
@ -631,6 +655,16 @@ class template_test extends \advanced_testcase {
'expected' => '|Some {fieldid} tag|', 'expected' => '|Some {fieldid} tag|',
'rolename' => 'student', 'rolename' => 'student',
], ],
'Student field#name tag' => [
'templatecontent' => 'Some [[myfield#name]] tag',
'expected' => '|Some {fieldname} tag|',
'rolename' => 'student',
],
'Student field#description tag' => [
'templatecontent' => 'Some [[myfield#description]] tag',
'expected' => '|Some {fielddescription} tag|',
'rolename' => 'student',
],
'Student comments name tag with comments enabled' => [ 'Student comments name tag with comments enabled' => [
'templatecontent' => 'Some ##comments## tag', 'templatecontent' => 'Some ##comments## tag',
'expected' => '|Some .*Comments.* tag|', 'expected' => '|Some .*Comments.* tag|',
@ -730,6 +764,16 @@ class template_test extends \advanced_testcase {
'enableratings' => false, 'enableratings' => false,
'options' => ['showmore' => true], 'options' => ['showmore' => true],
], ],
'Student otherfields tag' => [
'templatecontent' => 'Some ##otherfields## tag',
'expected' => '|Some .*{fieldname}.*Example entry.*otherfield.*Another example.* tag|',
'rolename' => 'student',
],
'Student otherfields tag with some field in the template' => [
'templatecontent' => 'Some [[myfield]] and ##otherfields## tag',
'expected' => '|Some .*Example entry.* and .*otherfield.*Another example.* tag|',
'rolename' => 'student',
],
]; ];
} }
@ -825,8 +869,11 @@ class template_test extends \advanced_testcase {
$fieldrecord = (object)[ $fieldrecord = (object)[
'name' => 'myfield', 'name' => 'myfield',
'type' => 'text', 'type' => 'text',
'description' => 'This is a field'
]; ];
$field = $generator->create_field($fieldrecord, $activity); $field = $generator->create_field($fieldrecord, $activity);
$otherfieldrecord = (object)['name' => 'otherfield', 'type' => 'text'];
$otherfield = $generator->create_field($otherfieldrecord, $activity);
if ($newentry) { if ($newentry) {
$entryid = null; $entryid = null;
@ -834,7 +881,10 @@ class template_test extends \advanced_testcase {
} else { } else {
$entryid = $generator->create_entry( $entryid = $generator->create_entry(
$activity, $activity,
[$field->field->id => 'Example entry'], [
$field->field->id => 'Example entry',
$otherfield->field->id => 'Another example',
],
0, 0,
['Cats', 'Dogs'] ['Cats', 'Dogs']
); );
@ -842,6 +892,7 @@ class template_test extends \advanced_testcase {
'd' => $activity->id, 'd' => $activity->id,
'rid' => $entryid, 'rid' => $entryid,
"field_{$field->field->id}" => "New value", "field_{$field->field->id}" => "New value",
"field_{$otherfield->field->id}" => "Altered value",
]; ];
} }
@ -850,11 +901,17 @@ class template_test extends \advanced_testcase {
// Some cooked variables for the regular expression. // Some cooked variables for the regular expression.
$replace = [ $replace = [
'{fieldid}' => $field->field->id, '{fieldid}' => $field->field->id,
'{fieldname}' => $field->field->name,
'{fielddescription}' => $field->field->description,
'{otherid}' => $otherfield->field->id,
]; ];
$processdata = (object)[ $processdata = (object)[
'generalnotifications' => ['GENERAL'], 'generalnotifications' => ['GENERAL'],
'fieldnotifications' => [$field->field->name => ['FIELD']], 'fieldnotifications' => [
$field->field->name => ['FIELD'],
$otherfield->field->name => ['OTHERFIELD'],
],
]; ];
$parser = new template($manager, $templatecontent); $parser = new template($manager, $templatecontent);
@ -889,6 +946,22 @@ class template_test extends \advanced_testcase {
'expected' => '|GENERAL.*Some field_{fieldid} tag|', 'expected' => '|GENERAL.*Some field_{fieldid} tag|',
'newentry' => false, 'newentry' => false,
], ],
'Teacher editing field#name tag' => [
'templatecontent' => 'Some [[myfield#name]] tag',
'expected' => '|GENERAL.*Some {fieldname} tag|',
'newentry' => false,
],
'Teacher editing field#description tag' => [
'templatecontent' => 'Some [[myfield#description]] tag',
'expected' => '|GENERAL.*Some {fielddescription} tag|',
'newentry' => false,
],
'Teacher editing entry field otherfields tag' => [
'templatecontent' => 'Some [[myfield]] and ##otherfields## tag',
'expected' => '|GENERAL.*Some .*FIELD.*field_{fieldid}.*input.*New value.* '
. 'and .*OTHERFIELD.*field_{otherid}.*input.*Altered value.* tag|',
'newentry' => false,
],
// New entry. // New entry.
'Teacher new entry tags tag' => [ 'Teacher new entry tags tag' => [
'templatecontent' => 'Some ##tags## tag', 'templatecontent' => 'Some ##tags## tag',
@ -905,6 +978,22 @@ class template_test extends \advanced_testcase {
'expected' => '|GENERAL.*Some field_{fieldid} tag|', 'expected' => '|GENERAL.*Some field_{fieldid} tag|',
'newentry' => true, 'newentry' => true,
], ],
'Teacher new entry field#name tag' => [
'templatecontent' => 'Some [[myfield#name]] tag',
'expected' => '|GENERAL.*Some {fieldname} tag|',
'newentry' => false,
],
'Teacher new entry field#description tag' => [
'templatecontent' => 'Some [[myfield#description]] tag',
'expected' => '|GENERAL.*Some {fielddescription} tag|',
'newentry' => false,
],
'Teacher new entry field otherfields tag' => [
'templatecontent' => 'Some [[myfield]] and ##otherfields## tag',
'expected' => '|GENERAL.*Some .*FIELD.*field_{fieldid}.*input.*New value.* '
. '.* and .*OTHERFIELD.*field_{otherid}.*input.*Altered value.* |',
'newentry' => false,
],
]; ];
} }
} }

View File

@ -4,6 +4,12 @@ information provided here is intended especially for developers.
== 4.2 == == 4.2 ==
* The field base class now has a method validate(). Overwrite it in the field type to provide validation of field type's * The field base class now has a method validate(). Overwrite it in the field type to provide validation of field type's
parameters in the field add/modify form. parameters in the field add/modify form.
* New tags are added to the current mod_data\templates class: ##otherfields##, [[FIELD#name]],
and [[FIELD#description]].
* The mod_data\template class can provide preprocessor methods to optimize some tags. From now on,
when load_template_tags detects a tag, it will call a "preprocess_tag_TAGNAME" method if it exists.
This preprocessing can be used, for example, to precalculate some content. Currently, this preprocessor
is used to detect which fields needs to be renderer when a ##otherfields## is used.
=== 4.1 === === 4.1 ===
* The method data_view is now deprecated. Use $maganer->set_module_viewed instead. * The method data_view is now deprecated. Use $maganer->set_module_viewed instead.