diff --git a/mod/data/classes/manager.php b/mod/data/classes/manager.php index 022ace17be8..0485bfa7d7f 100644 --- a/mod/data/classes/manager.php +++ b/mod/data/classes/manager.php @@ -209,6 +209,17 @@ class manager { $event->trigger(); } + /** + * Return if the database has records. + * + * @return bool true if the database has records + */ + public function has_records(): bool { + global $DB; + + return $DB->record_exists('data_records', ['dataid' => $this->instance->id]); + } + /** * Return if the database has fields. * diff --git a/mod/data/db/upgrade.php b/mod/data/db/upgrade.php index 38fd19e780a..a4b96e790e7 100644 --- a/mod/data/db/upgrade.php +++ b/mod/data/db/upgrade.php @@ -48,5 +48,21 @@ function xmldb_data_upgrade($oldversion) { // Automatically generated Moodle v4.2.0 release upgrade line. // Put any upgrade step following this. + if ($oldversion < 2023061300) { + // Clean orphan data_records. + $sql = "SELECT d.id FROM {data} d + LEFT JOIN {data_fields} f ON d.id = f.dataid + WHERE f.id IS NULL"; + $emptydatas = $DB->get_records_sql($sql); + if (!empty($emptydatas)) { + $dataids = array_keys($emptydatas); + list($datainsql, $dataparams) = $DB->get_in_or_equal($dataids, SQL_PARAMS_NAMED, 'data'); + $DB->delete_records_select('data_records', "dataid $datainsql", $dataparams); + } + + // Data savepoint reached. + upgrade_mod_savepoint(true, 2023061300, 'data'); + } + return true; } diff --git a/mod/data/lib.php b/mod/data/lib.php index 6dba4b82548..9835ecd0275 100644 --- a/mod/data/lib.php +++ b/mod/data/lib.php @@ -326,6 +326,8 @@ class data_field_base { // Base class for Database Field Types (see field/*/ global $DB; if (!empty($this->field->id)) { + $manager = manager::create_from_instance($this->data); + // Get the field before we delete it. $field = $DB->get_record('data_fields', array('id' => $this->field->id)); @@ -341,6 +343,11 @@ class data_field_base { // Base class for Database Field Types (see field/*/ 'dataid' => $this->data->id ) )); + + if (!$manager->has_fields() && $manager->has_records()) { + $DB->delete_records('data_records', ['dataid' => $this->data->id]); + } + $event->add_record_snapshot('data_fields', $field); $event->trigger(); } diff --git a/mod/data/tests/manager_test.php b/mod/data/tests/manager_test.php index 8828cb47345..5dcc4a3849b 100644 --- a/mod/data/tests/manager_test.php +++ b/mod/data/tests/manager_test.php @@ -164,6 +164,33 @@ class manager_test extends \advanced_testcase { $this->assertNotEmpty($event->get_name()); } + /** + * Test for has_records(). + * + * @covers ::has_records + */ + public function test_has_records() { + global $DB; + + $this->resetAfterTest(); + + $course = $this->getDataGenerator()->create_course(); + $data = $this->getDataGenerator()->create_module(manager::MODULE, ['course' => $course]); + $manager = manager::create_from_instance($data); + + // Empty database should return false. + $this->assertFalse($manager->has_records()); + + // Create data record. + $datarecords = new \stdClass(); + $datarecords->userid = '2'; + $datarecords->dataid = $data->id; + $datarecords->id = $DB->insert_record('data_records', $datarecords); + + // Database with records should return true. + $this->assertTrue($manager->has_records()); + } + /** * Test for has_fields(). * diff --git a/mod/data/version.php b/mod/data/version.php index 7dfb7c9b06f..0d47f616b0d 100644 --- a/mod/data/version.php +++ b/mod/data/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2023042400; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2023061300; // The current module version (Date: YYYYMMDDXX). $plugin->requires = 2023041800; // Requires this Moodle version. $plugin->component = 'mod_data'; // Full name of the plugin (used for diagnostics) $plugin->cron = 0;