Merge branch 'MDL-75497-master4' of https://github.com/raortegar/moodle

This commit is contained in:
Jun Pataleta 2022-10-20 17:29:11 +08:00
commit de11a92ed0
8 changed files with 157 additions and 37 deletions

View File

@ -19,6 +19,7 @@ namespace mod_data\local\importer;
use mod_data\manager;
use mod_data\preset;
use stdClass;
use html_writer;
/**
* Abstract class used for data preset importers
@ -212,7 +213,7 @@ abstract class preset_importer {
* @return bool Wether the importing has been successful.
*/
public function import(bool $overwritesettings): bool {
global $DB;
global $DB, $OUTPUT;
$params = $this->get_preset_settings();
$settings = $params->settings;
@ -252,7 +253,12 @@ abstract class preset_importer {
unset($fieldobject);
} else {
/* Make a new field */
include_once("field/$newfield->type/field.class.php");
$filepath = "field/$newfield->type/field.class.php";
if (!file_exists($filepath)) {
$missingfieldtypes[] = $newfield->name;
continue;
}
include_once($filepath);
if (!isset($newfield->description)) {
$newfield->description = '';
@ -263,6 +269,9 @@ abstract class preset_importer {
unset($fieldclass);
}
}
if (!empty($missingfieldtypes)) {
echo $OUTPUT->notification(get_string('missingfieldtypeimport', 'data') . html_writer::alist($missingfieldtypes));
}
}
// Get rid of all old unused data.

View File

@ -84,6 +84,9 @@ class template_editor_tools implements templatable, renderable {
$taglist = [];
$fields = $this->manager->get_fields();
foreach ($fields as $field) {
if ($field->type === 'unknown') {
continue;
}
$fieldname = $field->get_name();
$taglist["[[$fieldname]]"] = $fieldname;
}
@ -105,6 +108,9 @@ class template_editor_tools implements templatable, renderable {
// Field IDs.
$fields = $this->manager->get_fields();
foreach ($fields as $field) {
if ($field->type === 'unknown') {
continue;
}
$fieldname = $field->get_name();
$taglist["[[$fieldname#id]]"] = "$fieldname id";
}

View File

@ -299,6 +299,10 @@ class entry extends \core_search\base_mod {
foreach ($filteredcontents as $content) {
$classname = $this->get_field_class_name($content->fieldtype);
if (!$classname) {
$content->addtemplateposition = -1;
continue;
}
$content->priority = $classname::get_priority();
$content->addtemplateposition = strpos($template, '[['.$content->fldname.']]');
}
@ -346,16 +350,22 @@ class entry extends \core_search\base_mod {
}
/**
* Returns the class name for that field type and includes it.
* Returns the class name for the given field type and includes it.
*
* @param string $fieldtype
* @return string
* @return string|null It will return the class name or null if the field type is not available.
*/
protected function get_field_class_name($fieldtype) {
global $CFG;
$fieldtype = trim($fieldtype);
require_once($CFG->dirroot . '/mod/data/field/' . $fieldtype . '/field.class.php');
$fieldpath = $CFG->dirroot . '/mod/data/field/' . $fieldtype . '/field.class.php';
if (!file_exists($fieldpath)) {
return null;
}
require_once($fieldpath);
return 'data_field_' . $fieldtype;
}

View File

@ -850,7 +850,17 @@ class template {
$errors .= $renderer->notification($notification);
}
}
$replacements[] = $errors . $field->display_add_field($entryid, $entrydata);
$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.

View File

@ -260,9 +260,15 @@ switch ($mode) {
// Print confirmation message.
$field = data_get_field_from_id($fid, $data);
echo $OUTPUT->confirm('<strong>'.$field->name().': '.$field->field->name.'</strong><br /><br />'. get_string('confirmdeletefield','data'),
'field.php?d='.$data->id.'&mode=delete&fid='.$fid.'&confirm=1',
'field.php?d='.$data->id);
if ($field->type === 'unknown') {
$fieldtypename = get_string('unknown', 'data');
} else {
$fieldtypename = $field->name();
}
echo $OUTPUT->confirm('<strong>'.$fieldtypename.': '.$field->field->name.'</strong><br /><br />'.
get_string('confirmdeletefield', 'data'),
'field.php?d='.$data->id.'&mode=delete&fid='.$fid.'&confirm=1',
'field.php?d='.$data->id);
echo $OUTPUT->footer();
exit;
@ -317,6 +323,9 @@ $plugins = core_component::get_plugin_list('datafield');
$menufield = array();
foreach ($plugins as $plugin=>$fulldir){
if (!is_dir($fulldir)) {
continue;
}
$menufield[$plugin] = get_string('pluginname', 'datafield_'.$plugin); //get from language files
}
asort($menufield); //sort in alphabetical order
@ -360,6 +369,7 @@ if (($mode == 'new') && (!empty($newtype))) { // Adding a new field.
$table->wrap = array(false,false,false,false);
if ($fff = $DB->get_records('data_fields', array('dataid'=>$data->id),'id')){
$missingfieldtypes = [];
foreach ($fff as $ff) {
$field = data_get_field($ff, $data);
@ -378,15 +388,30 @@ if (($mode == 'new') && (!empty($newtype))) { // Adding a new field.
'mode' => 'delete',
));
$table->data[] = array(
html_writer::link($displayurl, $field->field->name),
$field->image() . '&nbsp;' . $field->name(),
// It display a notification when the field type does not exist.
$deletelink = html_writer::link($deleteurl, $OUTPUT->pix_icon('t/delete', get_string('delete')));
$editlink = html_writer::link($displayurl, $OUTPUT->pix_icon('t/edit', get_string('edit')));
if ($field->type === 'unknown') {
$missingfieldtypes[] = $field->field->name;
$fieldnamedata = $field->field->name;
$fieltypedata = $field->field->type;
$fieldlinkdata = $deletelink;
} else {
$fieldnamedata = html_writer::link($displayurl, $field->field->name);
$fieltypedata = $field->image() . '&nbsp;' . $field->name();
$fieldlinkdata = $editlink . '&nbsp;' . $deletelink;
}
$table->data[] = [
$fieldnamedata,
$fieltypedata,
$field->field->required ? get_string('yes') : get_string('no'),
shorten_text($field->field->description, 30),
html_writer::link($displayurl, $OUTPUT->pix_icon('t/edit', get_string('edit'))) .
'&nbsp;' .
html_writer::link($deleteurl, $OUTPUT->pix_icon('t/delete', get_string('delete'))),
);
$fieldlinkdata
];
}
if (!empty($missingfieldtypes)) {
echo $OUTPUT->notification(get_string('missingfieldtypes', 'data') . html_writer::alist($missingfieldtypes));
}
}
echo html_writer::table($table);

View File

@ -238,6 +238,11 @@ $string['invalidfieldid'] = 'Field ID is incorrect';
$string['invalidfieldname'] = 'Please choose another name for this field';
$string['invalidfieldtype'] = 'Field type is incorrect';
$string['invalidid'] = 'Incorrect data ID';
$string['missingfieldtype'] = 'Field type for {$a->name} not found';
$string['missingfieldtypes'] = 'The following fields do not have their corresponding field types installed and will not be included in the forms when adding or editing entries.
Their labels may still show on the form, so please update the "Add entry template" accordingly:';
$string['missingfieldtypeimport'] = 'The following fields were not imported because their corresponding field types are not installed:';
$string['unknown'] = 'Unknown field';
$string['invalidpreset'] = '{$a} is not a preset.';
$string['invalidrecord'] = 'Incorrect record';
$string['invalidurl'] = 'The URL you just entered is not valid';

View File

@ -400,6 +400,12 @@ class data_field_base { // Base class for Database Field Types (see field/*/
if (empty($this->field)) { // No field has been defined yet, try and make one
$this->define_default_field();
}
// Throw an exception if field type doen't exist. Anyway user should never access to edit a field with an unknown fieldtype.
if ($this->type === 'unknown') {
throw new \moodle_exception(get_string('missingfieldtype', 'data', (object)['name' => $this->field->name]));
}
echo $OUTPUT->box_start('generalbox boxaligncenter boxwidthwide');
echo '<form id="editfield" action="'.$CFG->wwwroot.'/mod/data/field.php" method="post">'."\n";
@ -417,7 +423,14 @@ class data_field_base { // Base class for Database Field Types (see field/*/
echo $OUTPUT->heading($this->name(), 3);
require_once($CFG->dirroot.'/mod/data/field/'.$this->type.'/mod.html');
$filepath = $CFG->dirroot.'/mod/data/field/'.$this->type.'/mod.html';
if (!file_exists($filepath)) {
throw new \moodle_exception(get_string('missingfieldtype', 'data', (object)['name' => $this->field->name]));
} else {
require_once($filepath);
}
echo html_writer::start_div('mt-3');
echo html_writer::tag('input', null, array('type' => 'submit', 'value' => $savebutton,
@ -916,7 +929,12 @@ function data_get_field_from_id($fieldid, $data){
function data_get_field_new($type, $data) {
global $CFG;
require_once($CFG->dirroot.'/mod/data/field/'.$type.'/field.class.php');
$filepath = $CFG->dirroot.'/mod/data/field/'.$type.'/field.class.php';
// It should never access this method if the subfield class doesn't exist.
if (!file_exists($filepath)) {
throw new \moodle_exception('invalidfieldtype', 'data');
}
require_once($filepath);
$newfield = 'data_field_'.$type;
$newfield = new $newfield(0, $data);
return $newfield;
@ -928,20 +946,24 @@ function data_get_field_new($type, $data) {
* input: $param $field - record from db
*
* @global object
* @param object $field
* @param object $data
* @param object $cm
* @return data_field_base
* @param stdClass $field the field record
* @param stdClass $data the data instance
* @param stdClass|null $cm optional course module data
* @return data_field_base the field object instance or data_field_base if unkown type
*/
function data_get_field($field, $data, $cm=null) {
global $CFG;
if ($field) {
require_once('field/'.$field->type.'/field.class.php');
$newfield = 'data_field_'.$field->type;
$newfield = new $newfield($field, $data, $cm);
return $newfield;
if (!isset($field->type)) {
return new data_field_base($field);
}
$filepath = $CFG->dirroot.'/mod/data/field/'.$field->type.'/field.class.php';
if (!file_exists($filepath)) {
return new data_field_base($field);
}
require_once($filepath);
$newfield = 'data_field_'.$field->type;
$newfield = new $newfield($field, $data, $cm);
return $newfield;
}
@ -1764,6 +1786,10 @@ function data_print_preference_form($data, $perpage, $search, $sort='', $order='
$fieldname = preg_quote($fieldname, '/');
$patterns[] = "/\[\[$fieldname\]\]/i";
$searchfield = data_get_field_from_id($field->field->id, $data);
if ($searchfield->type === 'unknown') {
continue;
}
if (!empty($search_array[$field->field->id]->data)) {
$replacement[] = $searchfield->display_search_field($search_array[$field->field->id]->data);
} else {
@ -2450,7 +2476,7 @@ abstract class data_preset_importer {
* @return bool
*/
function import($overwritesettings) {
global $DB, $CFG;
global $DB, $CFG, $OUTPUT;
$params = $this->get_preset_settings();
$settings = $params->settings;
@ -2471,7 +2497,7 @@ abstract class data_preset_importer {
}
else $preservedfields[$cid] = true;
}
$missingfieldtypes = [];
foreach ($newfields as $nid => $newfield) {
$cid = optional_param("field_$nid", -1, PARAM_INT);
@ -2488,7 +2514,12 @@ abstract class data_preset_importer {
unset($fieldobject);
} else {
/* Make a new field */
include_once("field/$newfield->type/field.class.php");
$filepath = "field/$newfield->type/field.class.php";
if (!file_exists($filepath)) {
$missingfieldtypes[] = $newfield->name;
continue;
}
include_once($filepath);
if (!isset($newfield->description)) {
$newfield->description = '';
@ -2499,6 +2530,9 @@ abstract class data_preset_importer {
unset($fieldclass);
}
}
if (!empty($missingfieldtypes)) {
echo $OUTPUT->notification(get_string('missingfieldtypeimport', 'data') . html_writer::alist($missingfieldtypes));
}
}
/* Get rid of all old unused data */
@ -2954,7 +2988,12 @@ function data_import_csv($cm, $data, &$csvdata, $encoding, $fielddelimiter) {
unset($fieldnames[$id]); // To ensure the user provided content fields remain in the array once flipped.
} else {
$field = $rawfields[$name];
require_once("$CFG->dirroot/mod/data/field/$field->type/field.class.php");
$filepath = "$CFG->dirroot/mod/data/field/$field->type/field.class.php";
if (!file_exists($filepath)) {
$errorfield .= "'$name' ";
continue;
}
require_once($filepath);
$classname = 'data_field_' . $field->type;
$fields[$name] = new $classname($field, $data, $cm);
}

View File

@ -270,7 +270,11 @@ class data_portfolio_caller extends portfolio_module_caller_base {
return true; // too early yet
}
foreach ($this->fieldtypes as $key => $field) {
require_once($CFG->dirroot . '/mod/data/field/' . $field .'/field.class.php');
$filepath = $CFG->dirroot . '/mod/data/field/' . $field .'/field.class.php';
if (!file_exists($filepath)) {
continue;
}
require_once($filepath);
$this->fields[$key] = unserialize(serialize($this->fields[$key]));
}
}
@ -974,7 +978,11 @@ function data_get_tag_title_field($dataid) {
if ($field->addtemplateposition === false) {
continue;
}
require_once($CFG->dirroot . '/mod/data/field/' . $field->type . '/field.class.php');
$filepath = $CFG->dirroot . '/mod/data/field/' . $field->type . '/field.class.php';
if (!file_exists($filepath)) {
continue;
}
require_once($filepath);
$classname = 'data_field_' . $field->type;
$field->priority = $classname::get_priority();
$filteredfields[] = $field;
@ -1005,11 +1013,19 @@ function data_get_tag_title_field($dataid) {
*
* @param stdClass $field The field from the 'data_fields' table
* @param stdClass $entry The entry from the 'data_records' table
* @return string The title of the entry
* @return string|null It will return the title of the entry or null if the field type is not available.
*/
function data_get_tag_title_for_entry($field, $entry) {
global $CFG, $DB;
require_once($CFG->dirroot . '/mod/data/field/' . $field->type . '/field.class.php');
if (!isset($field->type)) {
return null;
}
$filepath = $CFG->dirroot . '/mod/data/field/' . $field->type . '/field.class.php';
if (!file_exists($filepath)) {
return null;
}
require_once($filepath);
$classname = 'data_field_' . $field->type;
$sql = "SELECT dc.*
@ -1339,7 +1355,7 @@ function data_build_search_array($data, $paging, $searcharray, $defaults = null,
$searchfield = data_get_field_from_id($field->id, $data);
// Get field data to build search sql with. If paging is false, get from user.
// If paging is true, get data from $searcharray which is obtained from the $SESSION (see line 116).
if (!$paging) {
if (!$paging && $searchfield->type != 'unknown') {
$val = $searchfield->parse_search_field($defaults);
} else {
// Set value from session if there is a value @ the required index.