465 lines
18 KiB
PHP
465 lines
18 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @file classes/migration/upgrade/v3_4_0/MergeLocalesMigration.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 MergeLocalesMigration
|
|
*
|
|
* @brief Change Locales from locale_countryCode localization folder notation to locale localization folder notation
|
|
*/
|
|
|
|
namespace PKP\migration\upgrade\v3_4_0;
|
|
|
|
use Exception;
|
|
use Illuminate\Database\Schema\Blueprint;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use PKP\db\DAORegistry;
|
|
use PKP\install\DowngradeNotSupportedException;
|
|
|
|
abstract class MergeLocalesMigration extends \PKP\migration\Migration
|
|
{
|
|
protected string $CONTEXT_TABLE = '';
|
|
protected string $CONTEXT_SETTINGS_TABLE = '';
|
|
protected string $CONTEXT_COLUMN = '';
|
|
|
|
/**
|
|
* Run the migrations.
|
|
*/
|
|
public function up(): void
|
|
{
|
|
// This change fixes the locale column length on the static_page_settings
|
|
// which in 3.1.0 version was varchar(5).
|
|
if (Schema::hasTable('static_page_settings')) {
|
|
Schema::table('static_page_settings', function (Blueprint $table) {
|
|
$table->string('locale', 14)->change();
|
|
});
|
|
}
|
|
|
|
if (empty($this->CONTEXT_TABLE) || empty($this->CONTEXT_SETTINGS_TABLE) || empty($this->CONTEXT_COLUMN)) {
|
|
throw new Exception('Upgrade could not be completed because required properties for the MergeLocalesMigration migration are undefined.');
|
|
}
|
|
|
|
// All _settings tables.
|
|
foreach ($this->getSettingsTables() as $tableName => [$entityIdColumnName, $primaryKeyColumnName]) {
|
|
if (!Schema::hasTable($tableName) || !Schema::hasColumn($tableName, 'locale')) {
|
|
continue;
|
|
}
|
|
|
|
foreach (self::getAffectedLocales() as $source => $target) {
|
|
DB::table($tableName)
|
|
->where('locale', $source)
|
|
->update(['locale' => $target]);
|
|
}
|
|
}
|
|
|
|
// Tables
|
|
// site
|
|
$site = DB::table('site')
|
|
->select(['supported_locales', 'installed_locales', 'primary_locale'])
|
|
->first();
|
|
|
|
$this->updateArrayLocaleNoId($site->supported_locales, 'site', 'supported_locales');
|
|
$this->updateArrayLocaleNoId($site->installed_locales, 'site', 'installed_locales');
|
|
$this->updateSingleValueLocaleNoId($site->primary_locale, 'site', 'primary_locale');
|
|
|
|
Schema::table('site', function (Blueprint $table) {
|
|
$table->string('installed_locales')->default('en')->change();
|
|
});
|
|
|
|
// users
|
|
$migration = $this;
|
|
$users = DB::table('users')->chunkById(1000, function ($users) use ($migration) {
|
|
foreach ($users as $user) {
|
|
$migration->updateArrayLocale($user->locales, 'users', 'locales', 'user_id', $user->user_id);
|
|
}
|
|
}, 'user_id');
|
|
|
|
// submissions
|
|
$submissions = DB::table('submissions')->chunkById(1000, function ($submissions) use ($migration) {
|
|
foreach ($submissions as $submission) {
|
|
$migration->updateSingleValueLocale($submission->locale, 'submissions', 'locale', 'submission_id', $submission->submission_id);
|
|
}
|
|
}, 'submission_id');
|
|
|
|
|
|
// email_templates_default_data
|
|
$emailTemplatesDefaultData = DB::table('email_templates_default_data')
|
|
->get();
|
|
|
|
foreach ($emailTemplatesDefaultData as $emailTemplatesDefaultDataCurrent) {
|
|
$this->updateSingleValueLocaleEmailData($emailTemplatesDefaultDataCurrent->locale, 'email_templates_default_data', $emailTemplatesDefaultDataCurrent->email_key, $emailTemplatesDefaultData);
|
|
}
|
|
|
|
Schema::table('email_templates_default_data', function (Blueprint $table) {
|
|
$table->string('locale')->default('en')->change();
|
|
});
|
|
|
|
// Context
|
|
$contexts = DB::table($this->CONTEXT_TABLE)
|
|
->get();
|
|
|
|
foreach ($contexts as $context) {
|
|
$this->updateSingleValueLocale($context->primary_locale, $this->CONTEXT_TABLE, 'primary_locale', $this->CONTEXT_COLUMN, $context->{$this->CONTEXT_COLUMN});
|
|
}
|
|
|
|
$contextSettingsFormLocales = DB::table($this->CONTEXT_SETTINGS_TABLE)
|
|
->where('setting_name', '=', 'supportedFormLocales')
|
|
->get();
|
|
|
|
foreach ($contextSettingsFormLocales as $contextSettingsFormLocale) {
|
|
$this->updateArrayLocaleSetting($contextSettingsFormLocale->setting_value, $this->CONTEXT_SETTINGS_TABLE, 'supportedFormLocales', $this->CONTEXT_COLUMN, $contextSettingsFormLocale->{$this->CONTEXT_COLUMN});
|
|
}
|
|
|
|
$contextSettingsFormLocales = DB::table($this->CONTEXT_SETTINGS_TABLE)
|
|
->where('setting_name', '=', 'supportedLocales')
|
|
->get();
|
|
|
|
foreach ($contextSettingsFormLocales as $contextSettingsFormLocale) {
|
|
$this->updateArrayLocaleSetting($contextSettingsFormLocale->setting_value, $this->CONTEXT_SETTINGS_TABLE, 'supportedLocales', $this->CONTEXT_COLUMN, $contextSettingsFormLocale->{$this->CONTEXT_COLUMN});
|
|
}
|
|
|
|
$contextSettingsFormLocales = DB::table($this->CONTEXT_SETTINGS_TABLE)
|
|
->where('setting_name', '=', 'supportedSubmissionLocales')
|
|
->get();
|
|
|
|
foreach ($contextSettingsFormLocales as $contextSettingsFormLocale) {
|
|
$this->updateArrayLocaleSetting($contextSettingsFormLocale->setting_value, $this->CONTEXT_SETTINGS_TABLE, 'supportedSubmissionLocales', $this->CONTEXT_COLUMN, $contextSettingsFormLocale->{$this->CONTEXT_COLUMN});
|
|
}
|
|
|
|
// plugin_settings
|
|
// customBlockManager
|
|
$blockPluginName = 'customblockmanagerplugin';
|
|
$blockLocalizedSettingNames = ['blockTitle', 'blockContent'];
|
|
|
|
$contextIds = DB::table($this->CONTEXT_TABLE)
|
|
->get()
|
|
->pluck($this->CONTEXT_COLUMN);
|
|
|
|
foreach ($contextIds as $contextId) {
|
|
$blocks = DB::table('plugin_settings')
|
|
->where('plugin_name', '=', $blockPluginName)
|
|
->where('setting_name', '=', 'blocks')
|
|
->where('context_id', '=', $contextId)
|
|
->get()
|
|
->pluck('setting_value');
|
|
|
|
if (!$blocks->isEmpty()) {
|
|
$blocksArray = json_decode($blocks[0], true);
|
|
|
|
foreach ($blocksArray as $block) {
|
|
foreach ($blockLocalizedSettingNames as $blockLocalizedSettingName) {
|
|
$blockLocalizedContent = DB::table('plugin_settings')
|
|
->where('plugin_name', '=', $block)
|
|
->where('setting_name', '=', $blockLocalizedSettingName)
|
|
->where('context_id', '=', $contextId)
|
|
->first();
|
|
|
|
if (isset($blockLocalizedContent)) {
|
|
$this->updateArrayKeysLocaleSetting($blockLocalizedContent->setting_value, 'plugin_settings', 'plugin_setting_id', $blockLocalizedContent->plugin_setting_id);
|
|
}
|
|
}
|
|
}
|
|
|
|
$pluginSettingsDao = DAORegistry::getDAO('PluginSettingsDAO'); /** @var PluginSettingsDAO $pluginSettingsDao */
|
|
|
|
$cache = $pluginSettingsDao->_getCache($contextId, $blockPluginName);
|
|
$cache->flush();
|
|
}
|
|
}
|
|
}
|
|
|
|
public function updateArrayLocaleNoId(string $dbLocales, string $table, string $column)
|
|
{
|
|
$siteSupportedLocales = json_decode($dbLocales) ?? [];
|
|
|
|
if ($siteSupportedLocales !== false) {
|
|
$newLocales = [];
|
|
foreach ($siteSupportedLocales as $siteSupportedLocale) {
|
|
$updatedLocale = $this->getUpdatedLocale($siteSupportedLocale);
|
|
|
|
if (!is_null($updatedLocale)) {
|
|
if (!in_array($updatedLocale, $newLocales)) {
|
|
$newLocales[] = $updatedLocale;
|
|
}
|
|
} else {
|
|
$newLocales[] = $siteSupportedLocale;
|
|
}
|
|
}
|
|
|
|
DB::table($table)
|
|
->update([
|
|
$column => $newLocales
|
|
]);
|
|
}
|
|
}
|
|
|
|
public function updateArrayLocale(string $dbLocales, string $table, string $column, string $tableKeyColumn, int $id)
|
|
{
|
|
$siteSupportedLocales = json_decode($dbLocales) ?? [];
|
|
|
|
$newLocales = [];
|
|
foreach ($siteSupportedLocales as $siteSupportedLocale) {
|
|
$updatedLocale = $this->getUpdatedLocale($siteSupportedLocale);
|
|
|
|
if (!is_null($updatedLocale)) {
|
|
if (!in_array($updatedLocale, $newLocales)) {
|
|
$newLocales[] = $updatedLocale;
|
|
}
|
|
} else {
|
|
$newLocales[] = $siteSupportedLocale;
|
|
}
|
|
}
|
|
|
|
DB::table($table)
|
|
->where($tableKeyColumn, '=', $id)
|
|
->update([
|
|
$column => $newLocales
|
|
]);
|
|
}
|
|
|
|
public function updateArrayLocaleSetting(string $dbLocales, string $table, string $settingValue, string $tableKeyColumn, int $id)
|
|
{
|
|
$siteSupportedLocales = json_decode($dbLocales) ?? [];
|
|
|
|
if ($siteSupportedLocales !== false) {
|
|
$newLocales = [];
|
|
foreach ($siteSupportedLocales as $siteSupportedLocale) {
|
|
$updatedLocale = $this->getUpdatedLocale($siteSupportedLocale);
|
|
|
|
if (!is_null($updatedLocale)) {
|
|
if (!in_array($updatedLocale, $newLocales)) {
|
|
$newLocales[] = $updatedLocale;
|
|
}
|
|
} else {
|
|
$newLocales[] = $siteSupportedLocale;
|
|
}
|
|
}
|
|
|
|
DB::table($table)
|
|
->where($tableKeyColumn, '=', $id)
|
|
->where('setting_name', '=', $settingValue)
|
|
->update([
|
|
'setting_value' => $newLocales
|
|
]);
|
|
}
|
|
}
|
|
|
|
public function updateArrayKeysLocaleSetting(string $dbLocales, string $table, string $tableKeyColumn, int $id)
|
|
{
|
|
$siteSupportedLocales = json_decode($dbLocales, true) ?? [];
|
|
|
|
if ($siteSupportedLocales !== false) {
|
|
$newLocales = [];
|
|
foreach (array_keys($siteSupportedLocales) as $siteSupportedLocaleKey) {
|
|
$updatedLocale = $this->getUpdatedLocale($siteSupportedLocaleKey);
|
|
|
|
if (!is_null($updatedLocale)) {
|
|
$newLocales[$updatedLocale] = $siteSupportedLocales[$siteSupportedLocaleKey];
|
|
} else {
|
|
$newLocales[$siteSupportedLocaleKey] = $siteSupportedLocales[$siteSupportedLocaleKey];
|
|
}
|
|
}
|
|
|
|
$jsonString = json_encode($newLocales);
|
|
|
|
DB::table($table)
|
|
->where($tableKeyColumn, '=', $id)
|
|
->update([
|
|
'setting_value' => $jsonString
|
|
]);
|
|
}
|
|
}
|
|
|
|
public function updateSingleValueLocale(?string $localevalue, string $table, string $column, string $tableKeyColumn, int $id)
|
|
{
|
|
if ($localevalue === null) {
|
|
return;
|
|
}
|
|
|
|
$updatedLocale = $this->getUpdatedLocale($localevalue);
|
|
|
|
if (!is_null($updatedLocale)) {
|
|
DB::table($table)
|
|
->where($tableKeyColumn, '=', $id)
|
|
->update([
|
|
$column => $updatedLocale
|
|
]);
|
|
}
|
|
}
|
|
|
|
public function updateSingleValueLocaleNoId(string $localevalue, string $table, string $column)
|
|
{
|
|
$updatedLocale = $this->getUpdatedLocale($localevalue);
|
|
|
|
if (!is_null($updatedLocale)) {
|
|
DB::table($table)
|
|
->update([
|
|
$column => $updatedLocale
|
|
]);
|
|
}
|
|
}
|
|
|
|
public function updateSingleValueLocaleEmailData(string $localevalue, string $table, string $email_key, Collection $allEmailTemplateData)
|
|
{
|
|
$localeRows = DB::table($table)
|
|
->where('email_key', '=', $email_key)
|
|
->where('locale', '=', $localevalue);
|
|
|
|
$stillExists = $localeRows->exists();
|
|
|
|
if ($stillExists) {
|
|
$updatedLocale = $this->getUpdatedLocale($localevalue);
|
|
|
|
// if this is null we should do nothing - we are not handling this locale
|
|
if (!is_null($updatedLocale)) {
|
|
// if the updatedLocale is the same as the setting's locale we should do nothing
|
|
// Check if the database already has an updated locale with the same value -
|
|
$hasAlreadyExistingUpdatedLocale = DB::table($table)
|
|
->where('email_key', '=', $email_key)
|
|
->where('locale', '=', $updatedLocale)
|
|
->exists();
|
|
|
|
// if so, it is safe to delete the currently processed value.
|
|
if ($hasAlreadyExistingUpdatedLocale) {
|
|
$localeRows->delete();
|
|
} else {
|
|
$localeRows->update(['locale' => $updatedLocale]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns null if no conversion is available or
|
|
* a key value pair collection that the key is the output locale and the value is the defaultLocale.
|
|
*/
|
|
public function getUpdatedLocale(string $localeValue): ?string
|
|
{
|
|
$affectedLocales = $this->getAffectedLocales();
|
|
|
|
if ($affectedLocales->keys()->contains($localeValue)) {
|
|
$localeTransformation = $affectedLocales[$localeValue];
|
|
|
|
return $localeTransformation;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Reverse the downgrades
|
|
*
|
|
* @throws DowngradeNotSupportedException
|
|
*/
|
|
public function down(): void
|
|
{
|
|
throw new DowngradeNotSupportedException();
|
|
}
|
|
|
|
/**
|
|
* Get a list of settings tables, keyed by table name. Values are [entity_id_column_name, settings_table_id_column_name].
|
|
*/
|
|
protected static function getSettingsTables(): Collection
|
|
{
|
|
return collect([
|
|
'announcement_settings' => ['announcement_id', 'announcement_setting_id'],
|
|
'announcement_type_settings' => ['type_id', 'announcement_type_setting_id'],
|
|
'author_settings' => ['author_id', 'author_setting_id'],
|
|
'category_settings' => ['category_id', 'category_setting_id'],
|
|
'citation_settings' => ['citation_id', 'citation_setting_id'],
|
|
'controlled_vocab_entry_settings' => ['controlled_vocab_entry_id', 'controlled_vocab_entry_setting_id'],
|
|
'data_object_tombstone_settings' => ['tombstone_id', 'tombstone_setting_id'],
|
|
'email_templates_settings' => ['email_id', 'email_template_setting_id'],
|
|
'event_log_settings' => ['log_id', 'event_log_setting_id'],
|
|
'filter_settings' => ['filter_id', 'filter_setting_id'],
|
|
'genre_settings' => ['genre_id', 'genre_setting_id'],
|
|
'library_file_settings' => ['file_id', 'library_file_setting_id'],
|
|
'navigation_menu_item_assignment_settings' => ['navigation_menu_item_assignment_id', 'navigation_menu_item_assignment_setting_id'],
|
|
'navigation_menu_item_settings' => ['navigation_menu_item_id', 'navigation_menu_item_setting_id'],
|
|
'notification_settings' => ['notification_id', 'notification_setting_id'],
|
|
'notification_subscription_settings' => ['setting_id', 'notification_subscription_setting_id'],
|
|
'plugin_settings' => ['context_id', 'plugin_setting_id'],
|
|
'publication_settings' => ['publication_id', 'publication_setting_id'],
|
|
'review_form_element_settings' => ['review_form_element_id', 'review_form_element_setting_id'],
|
|
'review_form_settings' => ['review_form_id', 'review_form_setting_id'],
|
|
'submission_file_settings' => ['submission_file_id', 'submission_file_setting_id'],
|
|
'submission_settings' => ['submission_id', 'submission_setting_id'],
|
|
'user_group_settings' => ['user_group_id', 'user_group_setting_id'],
|
|
'user_settings' => ['user_id', 'user_setting_id'],
|
|
'site_settings' => [null, 'site_setting_id'],
|
|
'funder_settings' => ['funder_id', 'funder_setting_id'],
|
|
'funder_award_settings' => ['funder_award_id', 'funder_award_setting_id'],
|
|
'static_page_settings' => ['static_page_id', 'static_page_setting_id'],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Returns the effected locales along with the corresponding rename for each
|
|
*/
|
|
public static function getAffectedLocales(): Collection
|
|
{
|
|
return collect([
|
|
'es_ES' => 'es',
|
|
'en_US' => 'en',
|
|
'sr_RS@cyrillic' => 'sr@cyrillic',
|
|
'sr_RS@latin' => 'sr@latin',
|
|
'el_GR' => 'el',
|
|
'de_DE' => 'de',
|
|
'da_DK' => 'da',
|
|
'cs_CZ' => 'cs',
|
|
'ca_ES' => 'ca',
|
|
'bs_BA' => 'bs',
|
|
'bg_BG' => 'bg',
|
|
'be_BY@cyrillic' => 'be@cyrillic',
|
|
'az_AZ' => 'az',
|
|
'ar_IQ' => 'ar',
|
|
'fa_IR' => 'fa',
|
|
'fi_FI' => 'fi',
|
|
'gd_GB' => 'gd',
|
|
'gl_ES' => 'gl',
|
|
'he_IL' => 'he',
|
|
'hi_IN' => 'hi',
|
|
'hr_HR' => 'hr',
|
|
'hu_HU' => 'hu',
|
|
'hy_AM' => 'hy',
|
|
'id_ID' => 'id',
|
|
'is_IS' => 'is',
|
|
'it_IT' => 'it',
|
|
'ja_JP' => 'ja',
|
|
'ka_GE' => 'ka',
|
|
'kk_KZ' => 'kk',
|
|
'ko_KR' => 'ko',
|
|
'ku_IQ' => 'ku',
|
|
'lt_LT' => 'lt',
|
|
'lv_LV' => 'lv',
|
|
'mk_MK' => 'mk',
|
|
'mn_MN' => 'mn',
|
|
'ms_MY' => 'ms',
|
|
'nb_NO' => 'nb',
|
|
'nl_NL' => 'nl',
|
|
'pl_PL' => 'pl',
|
|
'ro_RO' => 'ro',
|
|
'ru_RU' => 'ru',
|
|
'si_LK' => 'si',
|
|
'sk_SK' => 'sk',
|
|
'sl_SI' => 'sl',
|
|
'sv_SE' => 'sv',
|
|
'tr_TR' => 'tr',
|
|
'uk_UA' => 'uk',
|
|
'ur_PK' => 'ur',
|
|
'uz_UZ@cyrillic' => 'uz@cyrillic',
|
|
'uz_UZ@latin' => 'uz@latin',
|
|
'vi_VN' => 'vi',
|
|
'eu_ES' => 'eu',
|
|
'sw_KE' => 'sw',
|
|
'zh_TW' => 'zh_Hant'
|
|
]);
|
|
}
|
|
}
|