795 lines
30 KiB
PHP
795 lines
30 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @file classes/migration/upgrade/v3_4_0/I7014_DoiMigration.php
|
|
*
|
|
* Copyright (c) 2014-2021 Simon Fraser University
|
|
* Copyright (c) 2000-2021 John Willinsky
|
|
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
|
*
|
|
* @class I7014_DoiMigration
|
|
*
|
|
* @brief Describe upgrade/downgrade operations for DB table dois.
|
|
*/
|
|
|
|
namespace APP\migration\upgrade\v3_4_0;
|
|
|
|
use Illuminate\Database\Query\Builder;
|
|
use Illuminate\Database\Schema\Blueprint;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use PKP\doi\Doi;
|
|
use PKP\install\DowngradeNotSupportedException;
|
|
use PKP\migration\upgrade\v3_4_0\PKPI7014_DoiMigration;
|
|
|
|
class I7014_DoiMigration extends PKPI7014_DoiMigration
|
|
{
|
|
/**
|
|
* Run the migrations.
|
|
*/
|
|
public function up(): void
|
|
{
|
|
parent::up();
|
|
|
|
// Add doiId to issue
|
|
Schema::table('issues', function (Blueprint $table) {
|
|
$table->bigInteger('doi_id')->nullable();
|
|
$table->foreign('doi_id')->references('doi_id')->on('dois')->nullOnDelete();
|
|
$table->index(['doi_id'], 'issues_doi_id');
|
|
});
|
|
|
|
// Add doiId to galley
|
|
Schema::table('publication_galleys', function (Blueprint $table) {
|
|
$table->bigInteger('doi_id')->nullable();
|
|
$table->foreign('doi_id')->references('doi_id')->on('dois')->nullOnDelete();
|
|
$table->index(['doi_id'], 'publication_galleys_doi_id');
|
|
});
|
|
|
|
$this->migrateExistingDataUp();
|
|
}
|
|
|
|
/**
|
|
* Reverse the downgrades
|
|
*
|
|
* @throws DowngradeNotSupportedException
|
|
*/
|
|
public function down(): void
|
|
{
|
|
throw new DowngradeNotSupportedException();
|
|
}
|
|
|
|
protected function migrateExistingDataUp(): void
|
|
{
|
|
parent::migrateExistingDataUp();
|
|
// Find all existing DOIs, move to new DOI objects and add foreign key for pub object
|
|
$this->_migrateGalleyDoisUp();
|
|
$this->_migrateIssueDoisUp();
|
|
$this->_migrateCrossrefSettingsToContext();
|
|
$this->_migrateDataciteSettingsToContext();
|
|
}
|
|
|
|
/**
|
|
* Transfer over batch_id, failedMsg and settings, filter info for importExport to generic plugin transfer
|
|
*/
|
|
private function _migrateCrossrefSettingsToContext()
|
|
{
|
|
// ===== Filters ===== //
|
|
DB::table('filters')
|
|
->where('class_name', '=', 'plugins.importexport.crossref.filter.IssueCrossrefXmlFilter')
|
|
->update(['class_name' => 'plugins.generic.crossref.filter.IssueCrossrefXmlFilter']);
|
|
DB::table('filters')
|
|
->where('class_name', '=', 'plugins.importexport.crossref.filter.ArticleCrossrefXmlFilter')
|
|
->update(['class_name' => 'plugins.generic.crossref.filter.ArticleCrossrefXmlFilter']);
|
|
|
|
// ===== Submissions Statuses & Settings ===== //
|
|
// 1. Get submissions with Crossref info
|
|
$publicationDois = DB::table('publications', 'p')
|
|
->select(['p.submission_id', 'p.doi_id'])
|
|
->whereNotNull('p.doi_id')
|
|
->get()
|
|
->map(function ($item) {
|
|
return [
|
|
'submission_id' => $item->submission_id,
|
|
'doi_id' => $item->doi_id
|
|
];
|
|
});
|
|
$galleyDois = DB::table('publication_galleys', 'pg')
|
|
->leftJoin('publications as p', 'pg.publication_id', '=', 'p.publication_id')
|
|
->select(['p.submission_id', 'pg.doi_id'])
|
|
->whereNotNull('pg.doi_id')
|
|
->get()
|
|
->map(function ($item) {
|
|
return [
|
|
'submission_id' => $item->submission_id,
|
|
'doi_id' => $item->doi_id
|
|
];
|
|
});
|
|
|
|
// 2. Get all DOIs possibly associated with submission (publications and galleys)
|
|
$doisBySubmission = $publicationDois->concat($galleyDois)
|
|
->mapToGroups(function ($item) {
|
|
return [$item['submission_id'] => $item['doi_id']];
|
|
})
|
|
->map(function ($item) {
|
|
return ['doiIds' => $item->all()];
|
|
})->toArray();
|
|
// 3. Apply batchId and failedMsg to all DOIs
|
|
DB::table('submissions', 's')
|
|
->leftJoin('submission_settings as ss', 's.submission_id', '=', 'ss.submission_id')
|
|
->whereIn('ss.setting_name', ['crossref::registeredDoi', 'crossref::status', 'crossref::batchId', 'crossref::failedMsg'])
|
|
->select(['ss.submission_id', 'ss.setting_name', 'ss.setting_value'])
|
|
->get()
|
|
->each(function ($item) use (&$doisBySubmission) {
|
|
if (!isset($doisBySubmission[$item->submission_id])) {
|
|
return;
|
|
}
|
|
switch ($item->setting_name) {
|
|
case 'crossref::registeredDoi':
|
|
$doisBySubmission[$item->submission_id]['crossref::registeredDoi'] = $item->setting_value;
|
|
return;
|
|
case 'crossref::status':
|
|
$status = Doi::STATUS_ERROR;
|
|
$registrationAgency = null;
|
|
if (in_array($item->setting_value, ['found', 'registered', 'markedRegistered'])) {
|
|
$status = Doi::STATUS_REGISTERED;
|
|
if ($item->setting_value == 'registered') {
|
|
$registrationAgency = 'CrossrefExportPlugin';
|
|
}
|
|
}
|
|
$doisBySubmission[$item->submission_id]['status'] = $status;
|
|
if ($registrationAgency !== null) {
|
|
$doisBySubmission[$item->submission_id]['registrationAgency'] = $registrationAgency;
|
|
}
|
|
return;
|
|
case 'crossref::batchId':
|
|
$doisBySubmission[$item->submission_id]['crossrefplugin_batchId'] = $item->setting_value;
|
|
return;
|
|
case 'crossref::failedMsg':
|
|
$doisBySubmission[$item->submission_id]['crossrefplugin_failedMsg'] = $item->setting_value;
|
|
return;
|
|
}
|
|
});
|
|
// 4. Apply status to all DOIs
|
|
$doiSettingInserts = [];
|
|
$doiStatusUpdates = [];
|
|
foreach ($doisBySubmission as $item) {
|
|
$doiIds = $item['doiIds'];
|
|
foreach ($doiIds as $doiId) {
|
|
// Settings
|
|
if (isset($item['crossrefplugin_batchId'])) {
|
|
$doiSettingInserts[] = [
|
|
'doi_id' => $doiId,
|
|
'setting_name' => 'crossrefplugin_batchId',
|
|
'setting_value' => $item['crossrefplugin_batchId'],
|
|
];
|
|
}
|
|
if (isset($item['crossrefplugin_failedMsg'])) {
|
|
$doiSettingInserts[] = [
|
|
'doi_id' => $doiId,
|
|
'setting_name' => 'crossrefplugin_failedMsg',
|
|
'setting_value' => $item['crossrefplugin_failedMsg'],
|
|
];
|
|
}
|
|
|
|
// Status
|
|
if (isset($item['status'])) {
|
|
$doiStatusUpdates[$doiId] = ['status' => $item['status']];
|
|
} elseif (isset($item['crossref::registeredDoi'])) {
|
|
$doiStatusUpdates[$doiId] = ['status' => 3];
|
|
}
|
|
|
|
if (isset($item['registrationAgency'])) {
|
|
$doiSettingInserts[] = [
|
|
'doi_id' => $doiId,
|
|
'setting_name' => 'registrationAgency',
|
|
'setting_value' => $item['registrationAgency']
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (array_chunk($doiSettingInserts, 100) as $chunkedInserts) {
|
|
DB::table('doi_settings')
|
|
->insert($chunkedInserts);
|
|
}
|
|
foreach ($doiStatusUpdates as $doiId => $doiStatusUpdate) {
|
|
DB::table('dois')
|
|
->where('doi_id', '=', $doiId)
|
|
->update($doiStatusUpdate);
|
|
}
|
|
|
|
// 5. Clean up old settings
|
|
DB::table('submission_settings')
|
|
->whereIn('setting_name', ['crossref::registeredDoi', 'crossref::status', 'crossref::batchId'])
|
|
->delete();
|
|
|
|
// ===== Issue Statuses & Settings ===== //
|
|
// 1. Get issues with Crossref-related info
|
|
$issueData = DB::table('issues', 'i')
|
|
->leftJoin('issue_settings as iss', 'i.issue_id', '=', 'iss.issue_id')
|
|
->whereIn('iss.setting_name', ['crossref::registeredDoi', 'crossref::status', 'crossref::batchId', 'crossref::failedMsg'])
|
|
->select(['i.issue_id', 'i.doi_id', 'iss.setting_name', 'iss.setting_value'])
|
|
->get()
|
|
->reduce(function ($carry, $item) {
|
|
if (!isset($carry[$item->issue_id])) {
|
|
$carry[$item->issue_id] = [
|
|
'doi_id' => $item->doi_id
|
|
];
|
|
}
|
|
|
|
$carry[$item->issue_id][$item->setting_name] = $item->setting_value;
|
|
return $carry;
|
|
}, []);
|
|
|
|
// 2. Map settings/status insert statements
|
|
$inserts = [];
|
|
$statuses = [];
|
|
foreach ($issueData as $item) {
|
|
// Settings
|
|
if (isset($item['crossref::batchId'])) {
|
|
$inserts[] = [
|
|
'doi_id' => $item['doi_id'],
|
|
'setting_name' => 'crossrefplugin_batchId',
|
|
'setting_value' => $item['crossref::batchId'],
|
|
];
|
|
}
|
|
|
|
if (isset($item['crossref::failedMsg'])) {
|
|
$inserts[] = [
|
|
'doi_id' => $item['doi_id'],
|
|
'setting_name' => 'crossrefplugin_failedMsg',
|
|
'setting_value' => $item['crossref::failedMsg'],
|
|
];
|
|
}
|
|
|
|
// Status
|
|
if (isset($item['crossref::status'])) {
|
|
$status = Doi::STATUS_ERROR;
|
|
$registrationAgency = null;
|
|
if (in_array($item['crossref::status'], ['found', 'registered', 'markedRegistered'])) {
|
|
$status = Doi::STATUS_REGISTERED;
|
|
if ($item['crossref::status'] === 'registered') {
|
|
$registrationAgency = 'CrossrefExportPlugin';
|
|
}
|
|
} elseif (isset($item['crossref::registeredDoi'])) {
|
|
$status = Doi::STATUS_REGISTERED;
|
|
}
|
|
$statuses[$item['doi_id']] = ['status' => $status];
|
|
if ($registrationAgency !== null) {
|
|
$inserts[] = [
|
|
'doi_id' => $item['doi_id'],
|
|
'setting_name' => 'registrationAgency',
|
|
'setting_value' => $registrationAgency
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
// 3. Insert updated settings/statuses
|
|
foreach (array_chunk($inserts, 100) as $chunkedInserts) {
|
|
DB::table('doi_settings')
|
|
->insert($chunkedInserts);
|
|
}
|
|
foreach ($statuses as $doiId => $insert) {
|
|
DB::table('dois')
|
|
->where('doi_id', '=', $doiId)
|
|
->update($insert);
|
|
}
|
|
|
|
// 4. Clean up old settings
|
|
DB::table('issue_settings')
|
|
->whereIn('setting_name', ['crossref::registeredDoi', 'crossref::status', 'crossref::batchId', 'crossref::failedMsg'])
|
|
->delete();
|
|
|
|
// ===== General cleanup ===== //
|
|
|
|
// If any Crossref settings are configured, assume plugin is in use and enable
|
|
$contextsWithPluginEnabled = DB::table('journals')
|
|
->whereIn('journal_id', function (Builder $q) {
|
|
$q->select('context_id')
|
|
->from('plugin_settings')
|
|
->where('plugin_name', '=', 'crossrefexportplugin');
|
|
})
|
|
->select(['journal_id'])
|
|
->get();
|
|
$contextsWithPluginEnabled->each(function ($item) {
|
|
DB::table('plugin_settings')
|
|
->insert(
|
|
[
|
|
'plugin_name' => 'crossrefplugin',
|
|
'context_id' => $item->journal_id,
|
|
'setting_name' => 'enabled',
|
|
'setting_value' => 1,
|
|
'setting_type' => 'bool'
|
|
]
|
|
);
|
|
});
|
|
|
|
// Enable automatic DOI deposit if configured
|
|
$contextsWithAutomaticDeposit = DB::table('journals')
|
|
->whereIn('journal_id', function (Builder $q) {
|
|
$q->select(['context_id'])
|
|
->from('plugin_settings')
|
|
->where('plugin_name', '=', 'crossrefexportplugin')
|
|
->where('setting_name', '=', 'automaticRegistration')
|
|
->where('setting_value', '=', 1) ;
|
|
})
|
|
->select(['journal_id'])
|
|
->get();
|
|
$contextsWithAutomaticDeposit->each(function ($item) {
|
|
DB::table('journal_settings')
|
|
->upsert(
|
|
[
|
|
'journal_id' => $item->journal_id,
|
|
'setting_name' => 'automaticDoiDeposit',
|
|
'setting_value' => 1
|
|
],
|
|
['journal_id', 'locale', 'setting_name'],
|
|
['setting_value']
|
|
);
|
|
});
|
|
|
|
DB::table('plugin_settings')
|
|
->where('plugin_name', '=', 'crossrefexportplugin')
|
|
->where('setting_name', '=', 'automaticRegistration')
|
|
->delete();
|
|
|
|
// Update no-longer-in-use version for importExport plugin
|
|
DB::table('versions')
|
|
->where('product_type', '=', 'plugins.importexport')
|
|
->where('product', '=', 'crossref')
|
|
->delete();
|
|
|
|
// Remove scheduled task
|
|
DB::table('scheduled_tasks')
|
|
->where('class_name', '=', 'plugins.importexport.crossref.CrossrefInfoSender')
|
|
->delete();
|
|
}
|
|
|
|
/**
|
|
* Transfer over settings, filter info for importExport to generic plugin transfer
|
|
*/
|
|
private function _migrateDataciteSettingsToContext()
|
|
{
|
|
// ===== Filters ===== //
|
|
DB::table('filters')
|
|
->where('class_name', '=', 'plugins.importexport.datacite.filter.DataciteXmlFilter')
|
|
->update(['class_name' => 'plugins.generic.datacite.filter.DataciteXmlFilter']);
|
|
|
|
// ===== Issues Statuses & Settings ===== //
|
|
// 1. Get issues with Datacite-related info
|
|
$issueData = DB::table('issues', 'i')
|
|
->leftJoin('issue_settings as iss', 'i.issue_id', '=', 'iss.issue_id')
|
|
->whereIn('iss.setting_name', ['datacite::registeredDoi', 'datacite::status'])
|
|
->select(['i.issue_id', 'i.doi_id', 'iss.setting_name', 'iss.setting_value'])
|
|
->get()
|
|
->reduce(function ($carry, $item) {
|
|
if (!isset($carry[$item->issue_id])) {
|
|
$carry[$item->issue_id] = [
|
|
'doi_id' => $item->doi_id
|
|
];
|
|
}
|
|
|
|
$carry[$item->issue_id][$item->setting_name] = $item->setting_value;
|
|
return $carry;
|
|
}, []);
|
|
|
|
// 2. Map statuses insert statements
|
|
$statuses = [];
|
|
$registrationAgencies = [];
|
|
foreach ($issueData as $item) {
|
|
// Status
|
|
if (isset($item['datacite::status'])) {
|
|
$status = Doi::STATUS_ERROR;
|
|
$registrationAgency = null;
|
|
if (in_array($item['datacite::status'], ['found', 'registered', 'markedRegistered'])) {
|
|
if ($item['datacite::status'] === 'registered') {
|
|
$registrationAgency = 'DataciteExportPlugin';
|
|
}
|
|
$status = Doi::STATUS_REGISTERED;
|
|
} elseif (isset($item['datacite::registeredDoi'])) {
|
|
$status = Doi::STATUS_REGISTERED;
|
|
}
|
|
$statuses[$item['doi_id']] = ['status' => $status];
|
|
$registrationAgencies[$item['doi_id']] = $registrationAgency;
|
|
}
|
|
}
|
|
|
|
// 3. Insert updated statuses
|
|
foreach ($statuses as $doiId => $insert) {
|
|
DB::table('dois')
|
|
->where('doi_id', '=', $doiId)
|
|
->update($insert);
|
|
}
|
|
|
|
foreach ($registrationAgencies as $doiId => $agency) {
|
|
if ($agency === null) {
|
|
continue;
|
|
}
|
|
|
|
DB::table('doi_settings')
|
|
->insert([
|
|
'doi_id' => $doiId,
|
|
'setting_name' => 'registrationAgency',
|
|
'setting_value' => $agency
|
|
]);
|
|
}
|
|
|
|
// 4. Clean up old settings
|
|
DB::table('issue_settings')
|
|
->whereIn('setting_name', ['datacite::registeredDoi', 'datacite::status'])
|
|
->delete();
|
|
|
|
// ===== Publications Statuses & Settings ===== //
|
|
// 1. Get publications with Datacite-related info
|
|
$publicationData = DB::table('submissions', 's')
|
|
->leftJoin('submission_settings as ss', 's.submission_id', '=', 'ss.submission_id')
|
|
->leftJoin('publications as p', 's.current_publication_id', '=', 'p.publication_id')
|
|
->whereIn('ss.setting_name', ['datacite::registeredDoi', 'datacite::status'])
|
|
->select(['p.publication_id', 'p.doi_id', 'ss.setting_name', 'ss.setting_value'])
|
|
->get()
|
|
->reduce(function ($carry, $item) {
|
|
if (!isset($carry[$item->publication_id])) {
|
|
$carry[$item->publication_id] = [
|
|
'doi_id' => $item->doi_id
|
|
];
|
|
}
|
|
|
|
$carry[$item->publication_id][$item->setting_name] = $item->setting_value;
|
|
return $carry;
|
|
}, []);
|
|
|
|
// 2. Map statuses insert statements
|
|
$statuses = [];
|
|
$registrationAgencies = [];
|
|
foreach ($publicationData as $item) {
|
|
// Status
|
|
if (isset($item['datacite::status'])) {
|
|
$status = Doi::STATUS_ERROR;
|
|
$registrationAgency = null;
|
|
if (in_array($item['datacite::status'], ['found', 'registered', 'markedRegistered'])) {
|
|
if ($item['datacite::status'] === 'registered') {
|
|
$registrationAgency = 'DataciteExportPlugin';
|
|
}
|
|
$status = Doi::STATUS_REGISTERED;
|
|
} elseif (isset($item['datacite::registeredDoi'])) {
|
|
$status = Doi::STATUS_REGISTERED;
|
|
}
|
|
$statuses[$item['doi_id']] = ['status' => $status];
|
|
$registrationAgencies[$item['doi_id']] = $registrationAgency;
|
|
}
|
|
}
|
|
|
|
// 3. Insert updated statuses
|
|
foreach ($statuses as $doiId => $insert) {
|
|
DB::table('dois')
|
|
->where('doi_id', '=', $doiId)
|
|
->update($insert);
|
|
}
|
|
|
|
foreach ($registrationAgencies as $doiId => $agency) {
|
|
if ($agency === null) {
|
|
continue;
|
|
}
|
|
|
|
DB::table('doi_settings')
|
|
->insert([
|
|
'doi_id' => $doiId,
|
|
'setting_name' => 'registrationAgency',
|
|
'setting_value' => $agency
|
|
]);
|
|
}
|
|
|
|
// 4. Clean up old settings
|
|
DB::table('publication_settings')
|
|
->whereIn('setting_name', ['datacite::registeredDoi', 'datacite::status'])
|
|
->delete();
|
|
|
|
// ===== Galleys Statuses & Settings ===== //
|
|
// 1. Get galleys with Datacite-related info
|
|
$galleyData = DB::table('publication_galleys', 'pg')
|
|
->leftJoin('publication_galley_settings as pgs', 'pg.galley_id', '=', 'pgs.galley_id')
|
|
->whereIn('pgs.setting_name', ['datacite::registeredDoi', 'datacite::status'])
|
|
->select(['pg.galley_id', 'pg.doi_id', 'pgs.setting_name', 'pgs.setting_value'])
|
|
->get()
|
|
->reduce(function ($carry, $item) {
|
|
if (!isset($carry[$item->galley_id])) {
|
|
$carry[$item->galley_id] = [
|
|
'doi_id' => $item->doi_id
|
|
];
|
|
}
|
|
|
|
$carry[$item->galley_id][$item->setting_name] = $item->setting_value;
|
|
return $carry;
|
|
}, []);
|
|
|
|
// 2. Map statuses insert statements
|
|
$statuses = [];
|
|
$registrationAgencies = [];
|
|
foreach ($galleyData as $item) {
|
|
// Status
|
|
if (isset($item['datacite::status'])) {
|
|
$status = Doi::STATUS_ERROR;
|
|
$registrationAgency = null;
|
|
if (in_array($item['datacite::status'], ['found', 'registered', 'markedRegistered'])) {
|
|
if ($item['datacite::status'] === 'registered') {
|
|
$registrationAgency = 'DataciteExportPlugin';
|
|
}
|
|
$status = Doi::STATUS_REGISTERED;
|
|
} elseif (isset($item['datacite::registeredDoi'])) {
|
|
$status = Doi::STATUS_REGISTERED;
|
|
}
|
|
$statuses[$item['doi_id']] = ['status' => $status];
|
|
$registrationAgencies[$item['doi_id']] = $registrationAgency;
|
|
}
|
|
}
|
|
|
|
// 3. Insert updated statuses
|
|
foreach ($statuses as $doiId => $insert) {
|
|
DB::table('dois')
|
|
->where('doi_id', '=', $doiId)
|
|
->update($insert);
|
|
}
|
|
|
|
foreach ($registrationAgencies as $doiId => $agency) {
|
|
if ($agency === null) {
|
|
continue;
|
|
}
|
|
|
|
DB::table('doi_settings')
|
|
->insert([
|
|
'doi_id' => $doiId,
|
|
'setting_name' => 'registrationAgency',
|
|
'setting_value' => $agency
|
|
]);
|
|
}
|
|
|
|
// 4. Clean up old settings
|
|
DB::table('publication_galley_settings')
|
|
->whereIn('setting_name', ['datacite::registeredDoi', 'datacite::status'])
|
|
->delete();
|
|
|
|
// ===== General cleanup ===== //
|
|
|
|
// If any Datacite settings are configured, assume plugin is in use and enable
|
|
$contextsWithPluginEnabled = DB::table('journals')
|
|
->whereIn('journal_id', function (Builder $q) {
|
|
$q->select('context_id')
|
|
->from('plugin_settings')
|
|
->where('plugin_name', '=', 'dataciteexportplugin');
|
|
})
|
|
->select(['journal_id'])
|
|
->get();
|
|
$contextsWithPluginEnabled->each(function ($item) {
|
|
DB::table('plugin_settings')
|
|
->insert(
|
|
[
|
|
'plugin_name' => 'dataciteplugin',
|
|
'context_id' => $item->journal_id,
|
|
'setting_name' => 'enabled',
|
|
'setting_value' => 1,
|
|
'setting_type' => 'bool'
|
|
]
|
|
);
|
|
});
|
|
|
|
// Enable automatic DOI deposit if configured
|
|
$contextsWithAutomaticDeposit = DB::table('journals')
|
|
->whereIn('journal_id', function (Builder $q) {
|
|
$q->select(['context_id'])
|
|
->from('plugin_settings')
|
|
->where('plugin_name', '=', 'dataciteexportplugin')
|
|
->where('setting_name', '=', 'automaticRegistration')
|
|
->where('setting_value', '=', 1) ;
|
|
})
|
|
->select(['journal_id'])
|
|
->get();
|
|
$contextsWithAutomaticDeposit->each(function ($item) {
|
|
DB::table('journal_settings')
|
|
->upsert(
|
|
[
|
|
'journal_id' => $item->journal_id,
|
|
'setting_name' => 'automaticDoiDeposit',
|
|
'setting_value' => 1
|
|
],
|
|
['journal_id', 'locale', 'setting_name'],
|
|
['setting_value']
|
|
);
|
|
});
|
|
|
|
DB::table('plugin_settings')
|
|
->where('plugin_name', '=', 'dataciteexportplugin')
|
|
->where('setting_name', '=', 'automaticRegistration')
|
|
->delete();
|
|
|
|
// Update no-longer-in-use version for importExport plugin
|
|
DB::table('versions')
|
|
->where('product_type', '=', 'plugins.importexport')
|
|
->where('product', '=', 'datacite')
|
|
->delete();
|
|
|
|
// Remove scheduled task
|
|
DB::table('scheduled_tasks')
|
|
->where('class_name', '=', 'plugins.importexport.datacite.DataciteInfoSender')
|
|
->delete();
|
|
}
|
|
|
|
/**
|
|
* Move galley DOIs from publication_galley_settings table to DOI objects
|
|
*/
|
|
private function _migrateGalleyDoisUp(): void
|
|
{
|
|
$q = DB::table('submissions', 's')
|
|
->select(['s.context_id', 'pg.galley_id', 'pg.doi_id', 'pgss.setting_name', 'pgss.setting_value'])
|
|
->leftJoin('publications as p', 'p.submission_id', '=', 's.submission_id')
|
|
->leftJoin('publication_galleys as pg', 'pg.publication_id', '=', 'p.publication_id')
|
|
->leftJoin('publication_galley_settings as pgss', 'pgss.galley_id', '=', 'pg.galley_id')
|
|
->where('pgss.setting_name', '=', 'pub-id::doi');
|
|
|
|
$q->chunkById(1000, function ($items) {
|
|
foreach ($items as $item) {
|
|
// Double-check to ensure a DOI object does not already exist for galley
|
|
if ($item->doi_id === null) {
|
|
$doiId = $this->_addDoi($item->context_id, $item->setting_value);
|
|
|
|
// Add association to newly created DOI to galley
|
|
DB::table('publication_galleys')
|
|
->where('galley_id', '=', $item->galley_id)
|
|
->update(['doi_id' => $doiId]);
|
|
} else {
|
|
// Otherwise update existing DOI object
|
|
$this->_updateDoi($item->doi_id, $item->context_id, $item->setting_value);
|
|
}
|
|
}
|
|
}, 'pg.galley_id', 'galley_id');
|
|
}
|
|
|
|
/**
|
|
* Move issue DOIs from issue_settings table to DOI objects
|
|
*/
|
|
private function _migrateIssueDoisUp(): void
|
|
{
|
|
$q = DB::table('issues', 'i')
|
|
->select(['i.issue_id', 'i.journal_id', 'i.doi_id', 'iss.setting_name', 'iss.setting_value'])
|
|
->leftJoin('issue_settings as iss', 'iss.issue_id', '=', 'i.issue_id')
|
|
->where('iss.setting_name', '=', 'pub-id::doi');
|
|
|
|
$q->chunkById(1000, function ($items) {
|
|
foreach ($items as $item) {
|
|
// Double-check to ensure a DOI object does not already exist for issue
|
|
if ($item->doi_id === null) {
|
|
$doiId = $this->_addDoi($item->journal_id, $item->setting_value);
|
|
|
|
// Add association to newly created DOI to issue
|
|
DB::table('issues')
|
|
->where('issue_id', '=', $item->issue_id)
|
|
->update(['doi_id' => $doiId]);
|
|
} else {
|
|
// Otherwise update existing DOI object
|
|
$this->_updateDoi($item->doi_id, $item->journal_id, $item->setting_value);
|
|
}
|
|
}
|
|
}, 'i.issue_id', 'issue_id');
|
|
}
|
|
|
|
/**
|
|
* Gets app-specific context table name, e.g. journals
|
|
*
|
|
*/
|
|
protected function getContextTable(): string
|
|
{
|
|
return 'journals';
|
|
}
|
|
|
|
/**
|
|
* Gets app-specific context_id column, e.g. journal_id
|
|
*/
|
|
protected function getContextIdColumn(): string
|
|
{
|
|
return 'journal_id';
|
|
}
|
|
|
|
/**
|
|
* Gets app-specific context settings table, e.g. journal_settings
|
|
*/
|
|
protected function getContextSettingsTable(): string
|
|
{
|
|
return 'journal_settings';
|
|
}
|
|
|
|
/**
|
|
* Adds app-specific suffix patterns to data collector stdClass
|
|
*/
|
|
protected function addSuffixPatternsData(\stdClass $data): \stdClass
|
|
{
|
|
$data->doiIssueSuffixPattern = [];
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Add suffix pattern settings from DB into reducer's data
|
|
*/
|
|
protected function insertSuffixPatternsData(\stdClass $carry, \stdClass $item): \stdClass
|
|
{
|
|
switch ($item->setting_name) {
|
|
case 'doiIssueSuffixPattern':
|
|
$carry->doiIssueSuffixPattern[] = [
|
|
$this->getContextIdColumn() => $item->context_id,
|
|
'setting_name' => $item->setting_name,
|
|
'setting_value' => $item->setting_value,
|
|
];
|
|
return $carry;
|
|
default:
|
|
return $carry;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add insert-ready statements for all applicable suffix pattern items
|
|
*/
|
|
protected function prepareSuffixPatternsForInsert(\stdClass $processedData, array $insertData): array
|
|
{
|
|
foreach ($processedData->doiIssueSuffixPattern as $item) {
|
|
$insertData[] = $item;
|
|
}
|
|
|
|
return $insertData;
|
|
}
|
|
|
|
/**
|
|
* Add app-specific enabled DOI types for insert into DB
|
|
*/
|
|
protected function insertEnabledDoiTypes(\stdClass $carry, \stdClass $item): \stdClass
|
|
{
|
|
if ($item->setting_name === 'enableIssueDoi') {
|
|
if (!isset($carry->enabledDoiTypes[$item->context_id])) {
|
|
$carry->enabledDoiTypes[$item->context_id] = [
|
|
$this->getContextIdColumn() => $item->context_id,
|
|
'setting_name' => 'enabledDoiTypes',
|
|
'setting_value' => [],
|
|
];
|
|
}
|
|
|
|
if ($item->setting_value === '1') {
|
|
$carry->enabledDoiTypes[$item->context_id]['setting_value'][] = 'issue';
|
|
}
|
|
}
|
|
|
|
return $carry;
|
|
}
|
|
|
|
/**
|
|
* Get an array with the keys for each suffix pattern type
|
|
*/
|
|
protected function getSuffixPatternNames(): array
|
|
{
|
|
return ['doiPublicationSuffixPattern', 'doiRepresentationSuffixPattern', 'doiIssueSuffixPattern'];
|
|
}
|
|
|
|
/**
|
|
* Returns the default pattern for the given suffix pattern type
|
|
*/
|
|
protected function getSuffixPatternValue(string $suffixPatternName): string
|
|
{
|
|
$pattern = '';
|
|
switch ($suffixPatternName) {
|
|
case 'doiPublicationSuffixPattern':
|
|
$pattern = '%j.v%vi%i.%a';
|
|
break;
|
|
case 'doiRepresentationSuffixPattern':
|
|
$pattern = '%j.v%vi%i.%a.g%g';
|
|
break;
|
|
case 'doiIssueSuffixPattern':
|
|
$pattern = '%j.v%vi%i';
|
|
break;
|
|
}
|
|
|
|
return $pattern;
|
|
}
|
|
}
|
|
|
|
if (!PKP_STRICT_MODE) {
|
|
class_alias('\APP\migration\upgrade\v3_4_0\I7014_DoiMigration', '\I7014_DoiMigration');
|
|
}
|