From e5abc3cf8dc8c401e0ae33fd9251e583f9f5a2cf Mon Sep 17 00:00:00 2001 From: Jonas Raoni Soares da Silva Date: Fri, 19 May 2023 13:38:53 +0300 Subject: [PATCH] pkp/pkp-lib#8333 Added missing foreign keys --- classes/migration/install/CommonMigration.php | 4 +- classes/migration/install/LogMigration.php | 4 +- .../migration/install/MetadataMigration.php | 15 ++- .../install/NavigationMenusMigration.php | 11 +- .../install/RolesAndUserGroupsMigration.php | 5 +- .../v3_4_0/I8333_AddMissingForeignKeys.php | 103 ++++++++++++++++++ 6 files changed, 133 insertions(+), 9 deletions(-) create mode 100644 classes/migration/upgrade/v3_4_0/I8333_AddMissingForeignKeys.php diff --git a/classes/migration/install/CommonMigration.php b/classes/migration/install/CommonMigration.php index 97cb194db9e..f117816493a 100644 --- a/classes/migration/install/CommonMigration.php +++ b/classes/migration/install/CommonMigration.php @@ -268,7 +268,9 @@ public function up(): void $table->comment('More data about plugins, including localized properties. This table is frequently used to store plugin-specific configuration.'); $table->bigIncrements('plugin_setting_id'); $table->string('plugin_name', 80); - $table->bigInteger('context_id'); + $table->bigInteger('context_id')->nullable(); + $table->foreign('context_id', 'plugin_settings_context_id')->references(Application::getContextDAO()->primaryKeyColumn)->on(Application::getContextDAO()->tableName)->onDelete('cascade'); + $table->index(['context_id'], 'plugin_settings_context_id'); $table->string('setting_name', 80); $table->mediumText('setting_value')->nullable(); $table->string('setting_type', 6)->comment('(bool|int|float|string|object)'); diff --git a/classes/migration/install/LogMigration.php b/classes/migration/install/LogMigration.php index 76442b67fbd..1f12ca79691 100644 --- a/classes/migration/install/LogMigration.php +++ b/classes/migration/install/LogMigration.php @@ -68,7 +68,9 @@ public function up(): void $table->bigInteger('log_id')->autoIncrement(); $table->bigInteger('assoc_type'); $table->bigInteger('assoc_id'); - $table->bigInteger('sender_id'); + $table->bigInteger('sender_id')->nullable(); + $table->foreign('sender_id', 'email_log_sender_id')->references('user_id')->on('users')->onDelete('cascade'); + $table->index(['sender_id'], 'email_log_sender_id'); $table->datetime('date_sent'); $table->bigInteger('event_type')->nullable(); $table->string('from_address', 255)->nullable(); diff --git a/classes/migration/install/MetadataMigration.php b/classes/migration/install/MetadataMigration.php index b70fd6d5669..439889bab9c 100644 --- a/classes/migration/install/MetadataMigration.php +++ b/classes/migration/install/MetadataMigration.php @@ -14,6 +14,7 @@ namespace PKP\migration\install; +use APP\core\Application; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; @@ -72,15 +73,23 @@ public function up(): void $table->comment('Filters represent a transformation of a supported piece of data from one form to another, such as a PHP object into an XML document.'); $table->bigInteger('filter_id')->autoIncrement(); - $table->bigInteger('filter_group_id')->default(0); + $table->bigInteger('filter_group_id'); $table->foreign('filter_group_id')->references('filter_group_id')->on('filter_groups')->onDelete('cascade'); $table->index(['filter_group_id'], 'filters_filter_group_id'); - $table->bigInteger('context_id')->default(0); + $contextDao = Application::getContextDAO(); + $table->bigInteger('context_id')->nullable(); + $table->foreign('context_id', 'filters_context_id')->references($contextDao->primaryKeyColumn)->on($contextDao->tableName)->onDelete('cascade'); + $table->index(['context_id'], 'filters_context_id'); + $table->string('display_name', 255)->nullable(); $table->string('class_name', 255)->nullable(); $table->smallInteger('is_template')->default(0); - $table->bigInteger('parent_filter_id')->default(0); + + $table->bigInteger('parent_filter_id')->nullable(); + $table->foreign('parent_filter_id')->references('filter_id')->on('filters')->onDelete('cascade'); + $table->index(['parent_filter_id'], 'filters_parent_filter_id'); + $table->bigInteger('seq')->default(0); }); diff --git a/classes/migration/install/NavigationMenusMigration.php b/classes/migration/install/NavigationMenusMigration.php index b27806ab4a2..ecec1251cda 100644 --- a/classes/migration/install/NavigationMenusMigration.php +++ b/classes/migration/install/NavigationMenusMigration.php @@ -14,6 +14,7 @@ namespace PKP\migration\install; +use APP\core\Application; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; @@ -28,7 +29,9 @@ public function up(): void Schema::create('navigation_menus', function (Blueprint $table) { $table->comment('Navigation menus on the website are installed with the software as a default set, and can be customized.'); $table->bigInteger('navigation_menu_id')->autoIncrement(); - $table->bigInteger('context_id'); + $table->bigInteger('context_id')->nullable(); + $table->foreign('context_id', 'navigation_menus_context_id')->references(Application::getContextDAO()->primaryKeyColumn)->on(Application::getContextDAO()->tableName)->onDelete('cascade'); + $table->index(['context_id'], 'navigation_menus_context_id'); $table->string('area_name', 255)->default('')->nullable(); $table->string('title', 255); }); @@ -37,7 +40,9 @@ public function up(): void Schema::create('navigation_menu_items', function (Blueprint $table) { $table->comment('Navigation menu items are single elements within a navigation menu.'); $table->bigInteger('navigation_menu_item_id')->autoIncrement(); - $table->bigInteger('context_id'); + $table->bigInteger('context_id')->nullable(); + $table->foreign('context_id', 'navigation_menu_items_context_id')->references(Application::getContextDAO()->primaryKeyColumn)->on(Application::getContextDAO()->tableName)->onDelete('cascade'); + $table->index(['context_id'], 'navigation_menu_items_context_id'); $table->string('path', 255)->default('')->nullable(); $table->string('type', 255)->default('')->nullable(); }); @@ -72,6 +77,8 @@ public function up(): void $table->index(['navigation_menu_item_id'], 'navigation_menu_item_assignments_navigation_menu_item_id'); $table->bigInteger('parent_id')->nullable(); + $table->foreign('parent_id', 'navigation_menu_item_assignments_parent_id')->references('navigation_menu_item_id')->on('navigation_menu_items')->onDelete('cascade'); + $table->index(['parent_id'], 'navigation_menu_item_assignments_parent_id'); $table->bigInteger('seq')->default(0)->nullable(); }); diff --git a/classes/migration/install/RolesAndUserGroupsMigration.php b/classes/migration/install/RolesAndUserGroupsMigration.php index 56cb46e674f..d2d68c75269 100644 --- a/classes/migration/install/RolesAndUserGroupsMigration.php +++ b/classes/migration/install/RolesAndUserGroupsMigration.php @@ -28,14 +28,15 @@ public function up(): void Schema::create('user_groups', function (Blueprint $table) { $table->comment('All defined user roles in a context, such as Author, Reviewer, Section Editor and Journal Manager.'); $table->bigInteger('user_group_id')->autoIncrement(); - $table->bigInteger('context_id'); + $table->bigInteger('context_id')->nullable(); + $table->foreign('context_id', 'user_groups_context_id')->references(Application::getContextDAO()->primaryKeyColumn)->on(Application::getContextDAO()->tableName)->onDelete('cascade'); + $table->index(['context_id'], 'user_groups_context_id'); $table->bigInteger('role_id'); $table->smallInteger('is_default')->default(0); $table->smallInteger('show_title')->default(1); $table->smallInteger('permit_self_registration')->default(0); $table->smallInteger('permit_metadata_edit')->default(0); $table->index(['user_group_id'], 'user_groups_user_group_id'); - $table->index(['context_id'], 'user_groups_context_id'); $table->index(['role_id'], 'user_groups_role_id'); }); diff --git a/classes/migration/upgrade/v3_4_0/I8333_AddMissingForeignKeys.php b/classes/migration/upgrade/v3_4_0/I8333_AddMissingForeignKeys.php new file mode 100644 index 00000000000..fa3af86ceb4 --- /dev/null +++ b/classes/migration/upgrade/v3_4_0/I8333_AddMissingForeignKeys.php @@ -0,0 +1,103 @@ +clearOrphanedEntities(); + $this->setupForeignKeys(); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + throw new DowngradeNotSupportedException(); + } + + protected function clearOrphanedEntities(): void + { + } + + protected function setupForeignKeys(): void + { + Schema::table('filters', function (Blueprint $table) { + // Only needed to fix the default value (0) + $table->bigInteger('filter_group_id')->default(null)->change(); + $table->bigInteger('parent_filter_id')->nullable()->default(null)->change(); + }); + DB::table('filters')->where('parent_filter_id', '=', 0)->update(['parent_filter_id' => null]); + Schema::table('filters', function (Blueprint $table) { + $table->foreign('parent_filter_id', 'filters_parent_filter_id')->references('filter_id')->on('filters')->onDelete('cascade'); + $table->index(['parent_filter_id'], 'filters_parent_filter_id'); + }); + + Schema::table( + 'navigation_menu_item_assignments', + fn (Blueprint $table) => $table->bigInteger('parent_id')->nullable()->default(null)->change() + ); + DB::table('navigation_menu_item_assignments')->where('parent_id', '=', 0)->update(['parent_id' => null]); + Schema::table( + 'navigation_menu_item_assignments', + function (Blueprint $table) { + $table->foreign('parent_id', 'navigation_menu_item_assignments_parent_id') + ->references('navigation_menu_item_id')->on('navigation_menu_items') + ->onDelete('cascade'); + $table->index(['parent_id'], 'navigation_menu_item_assignments_parent_id'); + } + ); + + // Entities missing the context_id foreign key + foreach (['navigation_menu_items', 'navigation_menus', 'plugin_settings', 'user_groups', 'filters'] as $tableName) { + Schema::table($tableName, fn (Blueprint $table) => $table->bigInteger('context_id')->nullable()->default(null)->change()); + DB::table($tableName)->where('context_id', '=', 0)->update(['context_id' => null]); + Schema::table( + $tableName, + function (Blueprint $table) use ($tableName) { + $table->foreign('context_id', "{$tableName}_context_id") + ->references($this->getContextKeyField()) + ->on($this->getContextTable())->onDelete('cascade'); + $table->index(['context_id'], "{$tableName}_context_id"); + } + ); + } + Schema::table('email_log', fn (Blueprint $table) => $table->bigInteger('sender_id')->nullable()->default(null)->change()); + DB::table('email_log')->where('sender_id', '=', 0)->update(['sender_id' => null]); + Schema::table( + 'email_log', + function (Blueprint $table) { + $table->foreign('sender_id', 'email_log_sender_id') + ->references('user_id')->on('users') + ->onDelete('cascade'); + $table->index(['sender_id'], 'email_log_sender_id'); + } + ); + } +}