diff --git a/mod/data/classes/local/importer/preset_importer.php b/mod/data/classes/local/importer/preset_importer.php index 6383b0bc811..afe48a1b7e0 100644 --- a/mod/data/classes/local/importer/preset_importer.php +++ b/mod/data/classes/local/importer/preset_importer.php @@ -240,7 +240,7 @@ abstract class preset_importer { * @return bool Wether the importing has been successful. */ public function import(bool $overwritesettings): bool { - global $DB, $OUTPUT; + global $DB, $OUTPUT, $CFG; $settings = $this->settings->settings; $currentfields = $this->settings->currentfields; @@ -250,8 +250,9 @@ abstract class preset_importer { foreach ($this->fieldstoupdate as $currentid => $updatable) { if ($currentid != -1 && isset($currentfields[$currentid])) { $fieldobject = data_get_field_from_id($currentfields[$currentid]->id, $module); + $toupdate = false; foreach ($updatable as $param => $value) { - if ($param != "id") { + if ($param != "id" && $fieldobject->field->$param !== $value) { $fieldobject->field->$param = $value; } } @@ -263,7 +264,7 @@ abstract class preset_importer { foreach ($this->fieldstocreate as $newfield) { /* Make a new field */ - $filepath = "field/$newfield->type/field.class.php"; + $filepath = $CFG->dirroot."/mod/data/field/$newfield->type/field.class.php"; if (!file_exists($filepath)) { $missingfieldtypes[] = $newfield->name; continue; @@ -285,10 +286,10 @@ abstract class preset_importer { // Get rid of all old unused data. foreach ($currentfields as $cid => $currentfield) { if (!array_key_exists($cid, $this->fieldstoupdate)) { - $id = $currentfield->id; - // Why delete existing data records and related comments/ratings?? - $DB->delete_records('data_content', ['fieldid' => $id]); - $DB->delete_records('data_fields', ['id' => $id]); + + // Delete all information related to fields. + $todelete = data_get_field_from_id($currentfield->id, $module); + $todelete->delete_field(); } } diff --git a/mod/data/lib.php b/mod/data/lib.php index 9ab3f3c45a8..34a093d7c00 100644 --- a/mod/data/lib.php +++ b/mod/data/lib.php @@ -1205,22 +1205,12 @@ function data_delete_instance($id) { // takes the dataid $cm = get_coursemodule_from_instance('data', $data->id); $context = context_module::instance($cm->id); -/// Delete all the associated information - - // files - $fs = get_file_storage(); - $fs->delete_area_files($context->id, 'mod_data'); - - // get all the records in this data - $sql = "SELECT r.id - FROM {data_records} r - WHERE r.dataid = ?"; - - $DB->delete_records_select('data_content', "recordid IN ($sql)", array($id)); - - // delete all the records and fields - $DB->delete_records('data_records', array('dataid'=>$id)); - $DB->delete_records('data_fields', array('dataid'=>$id)); + // Delete all information related to fields. + $fields = $DB->get_records('data_fields', ['dataid' => $id]); + foreach ($fields as $field) { + $todelete = data_get_field($field, $data, $cm); + $todelete->delete_field(); + } // Remove old calendar events. $events = $DB->get_records('event', array('modulename' => 'data', 'instance' => $id)); @@ -2562,10 +2552,9 @@ abstract class data_preset_importer { /* Data not used anymore so wipe! */ echo "Deleting field $currentfield->name
"; - $id = $currentfield->id; - // Why delete existing data records and related comments/ratings?? - $DB->delete_records('data_content', ['fieldid' => $id]); - $DB->delete_records('data_fields', ['id' => $id]); + // Delete all information related to fields. + $todelete = data_get_field_from_id($currentfield->id, $this->module); + $todelete->delete_field(); } } diff --git a/mod/data/tests/event/events_test.php b/mod/data/tests/event/events_test.php index a97aa7e22c9..6df9fb43650 100644 --- a/mod/data/tests/event/events_test.php +++ b/mod/data/tests/event/events_test.php @@ -25,6 +25,10 @@ namespace mod_data\event; +use mod_data\local\importer\preset_existing_importer; +use mod_data\manager; +use mod_data\preset; + class events_test extends \advanced_testcase { /** @@ -360,4 +364,127 @@ class events_test extends \advanced_testcase { $url = new \moodle_url('/mod/data/templates.php', array('d' => $data->id)); $this->assertEquals($url, $event->get_url()); } + + /** + * Data provider for build providers for test_needs_mapping and test_set_affected_fields. + * + * @return array[] + */ + public function preset_importer_provider(): array { + // Image gallery preset is: ['title' => 'text', 'description' => 'textarea', 'image' => 'picture']; + + $titlefield = new \stdClass(); + $titlefield->name = 'title'; + $titlefield->type = 'text'; + + $descfield = new \stdClass(); + $descfield->name = 'description'; + $descfield->type = 'textarea'; + + $imagefield = new \stdClass(); + $imagefield->name = 'image'; + $imagefield->type = 'picture'; + + $difffield = new \stdClass(); + $difffield->name = 'title'; + $difffield->type = 'textarea'; + + $newfield = new \stdClass(); + $newfield->name = 'number'; + $newfield->type = 'number'; + + return [ + 'Empty database / Importer with fields' => [ + 'currentfields' => [], + 'newfields' => [$titlefield, $descfield, $imagefield], + 'expected' => ['field_created' => 3], + ], + 'Database with fields / Empty importer' => [ + 'currentfields' => [$titlefield, $descfield, $imagefield], + 'newfields' => [], + 'expected' => ['field_deleted' => 3], + ], + 'Fields to create' => [ + 'currentfields' => [$titlefield, $descfield], + 'newfields' => [$titlefield, $descfield, $imagefield], + 'expected' => ['field_updated' => 2, 'field_created' => 1], + ], + 'Fields to remove' => [ + 'currentfields' => [$titlefield, $descfield, $imagefield, $difffield], + 'newfields' => [$titlefield, $descfield, $imagefield], + 'expected' => ['field_updated' => 2, 'field_deleted' => 1], + ], + 'Fields to update' => [ + 'currentfields' => [$difffield, $descfield, $imagefield], + 'newfields' => [$titlefield, $descfield, $imagefield], + 'expected' => ['field_updated' => 1, 'field_created' => 1, 'field_deleted' => 1], + ], + 'Fields to create, remove and update' => [ + 'currentfields' => [$titlefield, $descfield, $imagefield, $difffield], + 'newfields' => [$titlefield, $descfield, $newfield], + 'expected' => ['field_updated' => 2, 'field_created' => 1, 'field_deleted' => 2], + ], + ]; + } + /** + * Test for needs_mapping method. + * + * @dataProvider preset_importer_provider + * + * @param array $currentfields Fields of the current activity. + * @param array $newfields Fields to be imported. + * @param array $expected Expected events. + */ + public function test_importing_events( + array $currentfields, + array $newfields, + array $expected + ) { + + global $USER; + + $this->resetAfterTest(); + $this->setAdminUser(); + $plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_data'); + + // Create a course and a database activity. + $course = $this->getDataGenerator()->create_course(); + $activity = $this->getDataGenerator()->create_module(manager::MODULE, ['course' => $course]); + // Add current fields to the activity. + foreach ($currentfields as $field) { + $plugingenerator->create_field($field, $activity); + } + $manager = manager::create_from_instance($activity); + + $presetactivity = $this->getDataGenerator()->create_module(manager::MODULE, ['course' => $course]); + // Add current fields to the activity. + foreach ($newfields as $field) { + $plugingenerator->create_field($field, $presetactivity); + } + + $record = (object) [ + 'name' => 'Testing preset name', + 'description' => 'Testing preset description', + ]; + $saved = $plugingenerator->create_preset($presetactivity, $record); + $savedimporter = new preset_existing_importer($manager, $USER->id . '/Testing preset name'); + + // Trigger and capture the event for deleting the field. + $sink = $this->redirectEvents(); + $savedimporter->import(false); + $events = $sink->get_events(); + + foreach ($expected as $triggeredevent => $count) { + for ($i = 0; $i < $count; $i++) { + $event = array_shift($events); + + // Check that the event data is valid. + $this->assertInstanceOf('\mod_data\event\\'.$triggeredevent, $event); + $this->assertEquals(\context_module::instance($activity->cmid), $event->get_context()); + $this->assertEventContextNotUsed($event); + $url = new \moodle_url('/mod/data/field.php', ['d' => $activity->id]); + $this->assertEquals($url, $event->get_url()); + } + } + } }