diff --git a/_config/config.yml b/_config/config.yml index 2c5d726..3826785 100644 --- a/_config/config.yml +++ b/_config/config.yml @@ -9,6 +9,9 @@ SilverStripe\Control\Director: rules: at-taxonomy-overview: Chrometoaster\AdvancedTaxonomies\Controllers\TaxonomyOverviewController +Chrometoaster\AdvancedTaxonomies\Dev\AT4xMigrationTask: + enable_v4_migration: true + --- Only: moduleexists: 'silverstripe/cms' diff --git a/src/Dev/AT4xMigrationTask.php b/src/Dev/AT4xMigrationTask.php new file mode 100644 index 0000000..609bd00 --- /dev/null +++ b/src/Dev/AT4xMigrationTask.php @@ -0,0 +1,111 @@ +run(new HTTPRequest('GET', '/')); + } + + + /** + * @param HTTPRequest $request + * @throws Exception + */ + public function run($request) + { + if (!Config::forClass(self::class)->get('enable_v4_migration')) { + DB::get_schema()->alterationMessage('Data migration to Advanced Taxonomies 4.x format is disabled.', 'notice'); + + return; + } + + $schema = DataObject::getSchema(); + $termTable = $schema->tableName(TaxonomyTerm::class); + $baseObjectTable = $schema->tableName(BaseObject::class); + $baseTermTable = $schema->tableName(BaseTerm::class); + + // Safety net + if (!($baseObjectTable && $baseTermTable && $termTable)) { + throw new Exception(sprintf("One of the required db tables (%s, %s, %s) doesn't exist, did you run dev/build with a flush param?", $baseObjectTable, $baseTermTable, $termTable)); + } + + $versionedFields = array_keys(Config::inst()->get(Versioned::class, 'db_for_versions_table')); + + DB::get_conn()->withTransaction(function () use ($schema, $termTable, $versionedFields) { + + // cater for standard versioning db table suffiixes + $dbTableSuffixes = [ + '', + '_' . Versioned::LIVE, + '_Versions', // add RecordID and Version fields + ]; + + foreach ($dbTableSuffixes as $dbTableSuffix) { + foreach ([BaseObject::class, BaseTerm::class] as $model) { + + // get db table with suffix and all uninherited db fields + $dbTable = $schema->tableName($model) . $dbTableSuffix; + $dbFields = array_keys($schema->databaseFields($model, false)); + + // add special versioning fields + if ($dbTableSuffix === '_Versions') { + if (get_parent_class($model) === DataObject::class) { + array_push($dbFields, ...$versionedFields); + } else { + array_push($dbFields, 'RecordID', 'Version'); + } + } + + DB::get_schema()->alterationMessage(sprintf('Migrating data to %s table.', $dbTable), 'changed'); + + // make sure the table is empty to avoid foreign key conflicts + DB::query(sprintf('DELETE FROM "%s"', $dbTable)); + + // create a list of unique db table fields + $dbFieldsList = implode('","', array_unique($dbFields)); + + // prepare the insert query + $sql = sprintf( + 'INSERT INTO "%s" ("%s") SELECT "%s" FROM "%s"', + $dbTable, + $dbFieldsList, + $dbFieldsList, + $termTable . $dbTableSuffix + ); + + DB::query($sql); + } + } + + DB::get_schema()->alterationMessage('Taxonomy terms data migrated successfully into Advanced Taxonomies 4.x format.', 'changed'); + }, function () { + DB::get_schema()->alterationMessage('Failed to migrate taxonomy terms data to Advanced Taxonomies 4.x format.', 'error'); + }, false, true); + } +} diff --git a/src/Models/BaseObject.php b/src/Models/BaseObject.php index f3f3102..a39ec28 100644 --- a/src/Models/BaseObject.php +++ b/src/Models/BaseObject.php @@ -2,7 +2,9 @@ namespace Chrometoaster\AdvancedTaxonomies\Models; +use Chrometoaster\AdvancedTaxonomies\Dev\AT4MigrationTask; use Chrometoaster\AdvancedTaxonomies\Generators\URLSegmentGenerator; +use SilverStripe\Core\Config\Config; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\RequiredFields; use SilverStripe\i18n\i18n; @@ -285,4 +287,15 @@ public function providePermissions() ], ]; } + + + /** + * Trigger the 3.x to 4.x data migration (when enabled) + */ + public function requireDefaultRecords() + { + parent::requireDefaultRecords(); + + AT4MigrationTask::migrate(); + } }