diff --git a/mod/data/classes/local/importer/preset_importer.php b/mod/data/classes/local/importer/preset_importer.php
index 5b898290845..c5e48682847 100644
--- a/mod/data/classes/local/importer/preset_importer.php
+++ b/mod/data/classes/local/importer/preset_importer.php
@@ -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.
diff --git a/mod/data/classes/output/template_editor_tools.php b/mod/data/classes/output/template_editor_tools.php
index 54915c95c87..5302bfa0fed 100644
--- a/mod/data/classes/output/template_editor_tools.php
+++ b/mod/data/classes/output/template_editor_tools.php
@@ -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";
}
diff --git a/mod/data/classes/search/entry.php b/mod/data/classes/search/entry.php
index dc65a5751e7..95ee8a0a95c 100644
--- a/mod/data/classes/search/entry.php
+++ b/mod/data/classes/search/entry.php
@@ -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;
}
diff --git a/mod/data/classes/template.php b/mod/data/classes/template.php
index fec7402f261..96c2097e389 100644
--- a/mod/data/classes/template.php
+++ b/mod/data/classes/template.php
@@ -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.
diff --git a/mod/data/field.php b/mod/data/field.php
index 156c753d7a2..b5f02983d2f 100644
--- a/mod/data/field.php
+++ b/mod/data/field.php
@@ -260,9 +260,15 @@ switch ($mode) {
// Print confirmation message.
$field = data_get_field_from_id($fid, $data);
- echo $OUTPUT->confirm(''.$field->name().': '.$field->field->name.'
'. 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(''.$fieldtypename.': '.$field->field->name.'
'.
+ 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() . ' ' . $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() . ' ' . $field->name();
+ $fieldlinkdata = $editlink . ' ' . $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'))) .
- ' ' .
- 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);
diff --git a/mod/data/lang/en/data.php b/mod/data/lang/en/data.php
index 9ceef0f8d69..2f95d831a5d 100644
--- a/mod/data/lang/en/data.php
+++ b/mod/data/lang/en/data.php
@@ -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';
diff --git a/mod/data/lib.php b/mod/data/lib.php
index 9643740463f..8760c2e23eb 100644
--- a/mod/data/lib.php
+++ b/mod/data/lib.php
@@ -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 '