Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 31 additions & 174 deletions classes/migration/upgrade/v3_4_0/I7725_DecisionConstantsUpdate.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,181 +24,38 @@ class I7725_DecisionConstantsUpdate extends \PKP\migration\upgrade\v3_4_0\I7725_
*/
public function getDecisionMappings(): array
{
// stage_id filtering removed: all old OMP 3.3 decision values (after I7265
// stage-splitting) are unique, and the parent class's updated_at tracking
// mechanism prevents collisions between sequential mappings (e.g., 15→13
// then 13→11). OMP 3.3 had no validation on which decisions could be
// recorded at which stages, so decisions can exist at any stage in legacy data.
// See https://github.com/pkp/pkp-lib/issues/12357
return [
// \PKP\decision\Decision::INITIAL_DECLINE
[
'stage_id' => [WORKFLOW_STAGE_ID_SUBMISSION],
'current_value' => 9,
'updated_value' => 8,
],

// \PKP\decision\Decision::RECOMMEND_ACCEPT
[
'stage_id' => [WORKFLOW_STAGE_ID_EXTERNAL_REVIEW],
'current_value' => 11,
'updated_value' => 9,
],

// \PKP\decision\Decision::RECOMMEND_PENDING_REVISIONS
[
'stage_id' => [WORKFLOW_STAGE_ID_EXTERNAL_REVIEW],
'current_value' => 12,
'updated_value' => 10,
],

// \PKP\decision\Decision::RECOMMEND_RESUBMIT
[
'stage_id' => [WORKFLOW_STAGE_ID_EXTERNAL_REVIEW],
'current_value' => 13,
'updated_value' => 11,
],

// \PKP\decision\Decision::RECOMMEND_DECLINE
[
'stage_id' => [WORKFLOW_STAGE_ID_EXTERNAL_REVIEW],
'current_value' => 14,
'updated_value' => 12,
],

// \PKP\decision\Decision::RECOMMEND_EXTERNAL_REVIEW
[
'stage_id' => [WORKFLOW_STAGE_ID_EXTERNAL_REVIEW],
'current_value' => 15,
'updated_value' => 13,
],

// \PKP\decision\Decision::NEW_EXTERNAL_ROUND
[
'stage_id' => [WORKFLOW_STAGE_ID_EXTERNAL_REVIEW],
'current_value' => 16,
'updated_value' => 14,
],

// \PKP\decision\Decision::REVERT_DECLINE
[
'stage_id' => [WORKFLOW_STAGE_ID_EXTERNAL_REVIEW],
'current_value' => 17,
'updated_value' => 15,
],

// \PKP\decision\Decision::REVERT_INITIAL_DECLINE
[
'stage_id' => [WORKFLOW_STAGE_ID_SUBMISSION],
'current_value' => 18,
'updated_value' => 16,
],

// \PKP\decision\Decision::SKIP_EXTERNAL_REVIEW
[
'stage_id' => [WORKFLOW_STAGE_ID_EDITING],
'current_value' => 19,
'updated_value' => 17,
],

// \PKP\decision\Decision::SKIP_INTERNAL_REVIEW
[
'stage_id' => [WORKFLOW_STAGE_ID_EXTERNAL_REVIEW],
'current_value' => 20,
'updated_value' => 18,
],

// \PKP\decision\Decision::ACCEPT_INTERNAL
[
'stage_id' => [WORKFLOW_STAGE_ID_EDITING],
'current_value' => 21,
'updated_value' => 19,
],

// \PKP\decision\Decision::PENDING_REVISIONS_INTERNAL
[
'stage_id' => [WORKFLOW_STAGE_ID_INTERNAL_REVIEW],
'current_value' => 22,
'updated_value' => 20
],

// \PKP\decision\Decision::RESUBMIT_INTERNAL
[
'stage_id' => [],
'current_value' => 23,
'updated_value' => 21,
],

// \PKP\decision\Decision::DECLINE_INTERNAL
[
'stage_id' => [WORKFLOW_STAGE_ID_INTERNAL_REVIEW],
'current_value' => 24,
'updated_value' => 22,
],

// \PKP\decision\Decision::RECOMMEND_ACCEPT_INTERNAL
[
'stage_id' => [WORKFLOW_STAGE_ID_INTERNAL_REVIEW],
'current_value' => 25,
'updated_value' => 23,
],

// \PKP\decision\Decision::RECOMMEND_PENDING_REVISIONS_INTERNAL
[
'stage_id' => [WORKFLOW_STAGE_ID_INTERNAL_REVIEW],
'current_value' => 26,
'updated_value' => 24,
],

// \PKP\decision\Decision::RECOMMEND_RESUBMIT_INTERNAL
[
'stage_id' => [WORKFLOW_STAGE_ID_INTERNAL_REVIEW],
'current_value' => 27,
'updated_value' => 25,
],

// \PKP\decision\Decision::RECOMMEND_DECLINE_INTERNAL
[
'stage_id' => [],
'current_value' => 28,
'updated_value' => 26,
],

// \PKP\decision\Decision::REVERT_INTERNAL_DECLINE
[
'stage_id' => [WORKFLOW_STAGE_ID_INTERNAL_REVIEW],
'current_value' => 29,
'updated_value' => 27,
],

// \PKP\decision\Decision::NEW_INTERNAL_ROUND
[
'stage_id' => [WORKFLOW_STAGE_ID_INTERNAL_REVIEW],
'current_value' => 30,
'updated_value' => 28,
],

// \PKP\decision\Decision::BACK_FROM_PRODUCTION
[
'stage_id' => [WORKFLOW_STAGE_ID_EDITING],
'current_value' => 31,
'updated_value' => 29,
],

// \PKP\decision\Decision::BACK_FROM_COPYEDITING
[
'stage_id' => [WORKFLOW_STAGE_ID_SUBMISSION, WORKFLOW_STAGE_ID_INTERNAL_REVIEW, WORKFLOW_STAGE_ID_EXTERNAL_REVIEW],
'current_value' => 32,
'updated_value' => 30,
],

// \PKP\decision\Decision::CANCEL_REVIEW_ROUND
[
'stage_id' => [WORKFLOW_STAGE_ID_SUBMISSION, WORKFLOW_STAGE_ID_INTERNAL_REVIEW, WORKFLOW_STAGE_ID_EXTERNAL_REVIEW],
'current_value' => 33,
'updated_value' => 31,
],

// \PKP\decision\Decision::CANCEL_INTERNAL_REVIEW_ROUND
[
'stage_id' => [WORKFLOW_STAGE_ID_SUBMISSION, WORKFLOW_STAGE_ID_INTERNAL_REVIEW],
'current_value' => 34,
'updated_value' => 32,
],
['current_value' => 9, 'updated_value' => 8], // INITIAL_DECLINE
['current_value' => 11, 'updated_value' => 9], // RECOMMEND_ACCEPT
['current_value' => 12, 'updated_value' => 10], // RECOMMEND_PENDING_REVISIONS
['current_value' => 13, 'updated_value' => 11], // RECOMMEND_RESUBMIT
['current_value' => 14, 'updated_value' => 12], // RECOMMEND_DECLINE
['current_value' => 15, 'updated_value' => 13], // RECOMMEND_EXTERNAL_REVIEW
['current_value' => 16, 'updated_value' => 14], // NEW_EXTERNAL_ROUND
['current_value' => 17, 'updated_value' => 15], // REVERT_DECLINE
['current_value' => 18, 'updated_value' => 16], // REVERT_INITIAL_DECLINE
['current_value' => 19, 'updated_value' => 17], // SKIP_EXTERNAL_REVIEW
['current_value' => 20, 'updated_value' => 18], // SKIP_INTERNAL_REVIEW
['current_value' => 21, 'updated_value' => 19], // ACCEPT_INTERNAL
['current_value' => 22, 'updated_value' => 20], // PENDING_REVISIONS_INTERNAL
['current_value' => 23, 'updated_value' => 21], // RESUBMIT_INTERNAL
['current_value' => 24, 'updated_value' => 22], // DECLINE_INTERNAL
['current_value' => 25, 'updated_value' => 23], // RECOMMEND_ACCEPT_INTERNAL
['current_value' => 26, 'updated_value' => 24], // RECOMMEND_PENDING_REVISIONS_INTERNAL
['current_value' => 27, 'updated_value' => 25], // RECOMMEND_RESUBMIT_INTERNAL
['current_value' => 28, 'updated_value' => 26], // RECOMMEND_DECLINE_INTERNAL
['current_value' => 29, 'updated_value' => 27], // REVERT_INTERNAL_DECLINE
['current_value' => 30, 'updated_value' => 28], // NEW_INTERNAL_ROUND
['current_value' => 31, 'updated_value' => 29], // BACK_FROM_PRODUCTION
['current_value' => 32, 'updated_value' => 30], // BACK_FROM_COPYEDITING
['current_value' => 33, 'updated_value' => 31], // CANCEL_REVIEW_ROUND
['current_value' => 34, 'updated_value' => 32], // CANCEL_INTERNAL_REVIEW_ROUND
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@

namespace APP\migration\upgrade\v3_5_0;

use APP\core\Application;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use PKP\install\DowngradeNotSupportedException;

class I11241_MissingDecisionConstantsUpdate extends \PKP\migration\upgrade\v3_4_0\I7725_DecisionConstantsUpdate
{
/**
Expand All @@ -31,6 +36,15 @@ public function getDecisionMappings(): array
'updated_value' => 17,
],

// \PKP\decision\Decision::RECOMMEND_EXTERNAL_REVIEW
// OMP 3.3 only offered this at INTERNAL_REVIEW stage
// See https://github.com/pkp/pkp-lib/issues/12357
[
'stage_id' => [WORKFLOW_STAGE_ID_INTERNAL_REVIEW],
'current_value' => 15,
'updated_value' => 13,
],

// \PKP\decision\Decision::BACK_FROM_PRODUCTION
[
'stage_id' => [WORKFLOW_STAGE_ID_PRODUCTION],
Expand All @@ -46,4 +60,81 @@ public function getDecisionMappings(): array
],
];
}

/**
* Run the migrations.
*/
public function up(): void
{
// If the first installed version is 3.4.0-*
// nothing to do and return
$firstInstalledVersion = DB::table('versions')
->where('product', Application::get()->getName())
->where('product_type', 'core')
->orderBy('date_installed')
->first();

if ($firstInstalledVersion->major == 3 && $firstInstalledVersion->minor == 4) {
return;
}

// Get the current version from which is the upgrading is happening
$currentVersion = DB::table('versions')
->where('product', Application::get()->getName())
->where('product_type', 'core')
->where('current', 1)
->first();

// If NOT upgrading from 3.4.0-*, then fixed migration \APP\migration\upgrade\v3_4_0\I7725_DecisionConstantsUpdate
// have the new fix in place and rest of the code does not need to execute
if ($currentVersion->major == 3 && $currentVersion->minor != 4) {
return;
}

// If upgrading from 3.4.0-11 or above, then we have a fixed applied also for it
// at https://github.com/pkp/pkp-lib/issues/12140
// so nothing to do and return
if ($currentVersion->major == 3 && $currentVersion->minor == 4 && $currentVersion->build >= 11) {
return;
}

// Upgrading from a 3.4.0-10 or below version
// Need to figure out the first installed date of 3.4.0-*
// Then need to update the decisions made before the first version of 3.4.0-* installed
$firstVersionOf34 = DB::table('versions')
->where('product', Application::get()->getName())
->where('product_type', 'core')
->where('major', 3)
->where('minor', 4)
->orderBy('date_installed')
->first();

$this->configureUpdatedAtColumn();

collect($this->getDecisionMappings())
->each(
fn ($decisionMapping) => DB::table('edit_decisions')
->when(
isset($decisionMapping['stage_id']) && !empty($decisionMapping['stage_id']),
fn ($query) => $query->whereIn('stage_id', $decisionMapping['stage_id'])
)
->where('decision', $decisionMapping['current_value'])
->whereNull('updated_at')
->where('date_decided', '<', $firstVersionOf34->date_installed)
->update([
'decision' => $decisionMapping['updated_value'],
'updated_at' => Carbon::now(),
])
);

$this->removeUpdatedAtColumn();
}

/**
* Reverse the migrations.
*/
public function down(): void
{
throw new DowngradeNotSupportedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

/**
* @file classes/migration/upgrade/v3_5_0/I12357_FixDecisionConstantsMissedStageId.php
*
* Copyright (c) 2025 Simon Fraser University
* Copyright (c) 2025 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class I12357_FixDecisionConstantsMissedStageId
*
* @brief Fix RECOMMEND_EXTERNAL_REVIEW decisions missed by previous migrations.
* OMP 3.3 offered RECOMMEND_EXTERNAL_REVIEW only at INTERNAL_REVIEW stage,
* but I7725 only mapped it at EXTERNAL_REVIEW, and I11241 did not include it.
*
* @see https://github.com/pkp/pkp-lib/issues/12357
*/

namespace APP\migration\upgrade\v3_5_0;

use APP\core\Application;
use Illuminate\Support\Facades\DB;
use PKP\install\DowngradeNotSupportedException;

class I12357_FixDecisionConstantsMissedStageId extends \PKP\migration\upgrade\v3_4_0\I7725_DecisionConstantsUpdate
{
/**
* Get the decisions constants mappings
*/
public function getDecisionMappings(): array
{
// Only RECOMMEND_EXTERNAL_REVIEW (15→13) is targeted here.
// This is collision-safe because correctly-migrated REVERT_DECLINE rows
// (17→15) are at EXTERNAL_REVIEW stage, not INTERNAL_REVIEW.
return [
[
'stage_id' => [WORKFLOW_STAGE_ID_INTERNAL_REVIEW],
'current_value' => 15,
'updated_value' => 13,
],
];
}

/**
* Run the migrations.
*/
public function up(): void
{
// If the first installed version is 3.4.0+, no pre-3.4 legacy data exists
$firstInstalledVersion = DB::table('versions')
->where('product', Application::get()->getName())
->where('product_type', 'core')
->orderBy('date_installed')
->first();

if ($firstInstalledVersion->major > 3 || ($firstInstalledVersion->major == 3 && $firstInstalledVersion->minor >= 4)) {
return;
}

// Run the parent's up() which uses configureUpdatedAtColumn(),
// iterates mappings with whereNull('updated_at'), and removeUpdatedAtColumn().
// Already-migrated RECOMMEND_EXTERNAL_REVIEW rows have decision=13 (not 15),
// so WHERE decision=15 only matches stranded rows.
parent::up();
}

/**
* Reverse the migrations.
*/
public function down(): void
{
throw new DowngradeNotSupportedException();
}
}
Loading
Loading