mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
ENHANCEMENT Adapted MigrateTranslatableTask to new Locale datamodel and fixed some inconsistencies with translation groups, duplicate records etc
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@75678 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
332e231529
commit
9306b8b065
@ -1,5 +1,38 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
|
* Migrates the old Translatable datamodel introduced in SilverStripe 2.1 to the new schema
|
||||||
|
* introduced in SilverStripe 2.3.2.
|
||||||
|
* Just works for {@link SiteTree} records and subclasses. If you have used the Translatable
|
||||||
|
* extension on other {@link DataObject} subclasses before, this script won't migrate them automatically.
|
||||||
|
*
|
||||||
|
* <h2>Limitations</h2>
|
||||||
|
*
|
||||||
|
* - Information from the {@link Versioned} extension (e.g. in "SiteTree_versions" table)
|
||||||
|
* will be discarded for translated records.
|
||||||
|
* - Custom translatable fields on your own {@link Page} class or subclasses thereof won't
|
||||||
|
* be migrated into the translation.
|
||||||
|
* - 2.1-style subtags of a language (e.g. "en") will be automatically disambiguated to their full
|
||||||
|
* locale value (e.g. "en_US"), by the lookup defined in {@link i18n::get_locale_from_lang()}.
|
||||||
|
* - Doesn't detect published translations when the script is run twice on the same data set
|
||||||
|
*
|
||||||
|
* <h2>Usage</h2>
|
||||||
|
*
|
||||||
|
* PLEASE BACK UP YOUR DATABASE BEFORE RUNNING THIS SCRIPT.
|
||||||
|
*
|
||||||
|
* Warning: Please run dev/build on your 2.2 database to update the schema before running this task.
|
||||||
|
* The dev/build command will rename tables like "SiteTree_lang" to "_obsolete_SiteTree_lang".
|
||||||
|
*
|
||||||
|
* <h3>Commandline</h3>
|
||||||
|
* Requires "sake" tool (see http://doc.silverstripe.com/?id=sake)
|
||||||
|
* <example>
|
||||||
|
* sake dev/tasks/MigrateTranslatableTask
|
||||||
|
* </example>
|
||||||
|
*
|
||||||
|
* <h3>Browser</h3>
|
||||||
|
* <example>
|
||||||
|
* http://mydomain.com/dev/tasks/MigrateTranslatableTask
|
||||||
|
* </example>
|
||||||
|
*
|
||||||
* @package sapphire
|
* @package sapphire
|
||||||
* @subpackage tasks
|
* @subpackage tasks
|
||||||
*/
|
*/
|
||||||
@ -16,34 +49,82 @@ class MigrateTranslatableTask extends BuildTask {
|
|||||||
function run($request) {
|
function run($request) {
|
||||||
$ids = array();
|
$ids = array();
|
||||||
|
|
||||||
//$_REQUEST['showqueries'] = 1;
|
echo "#################################\n";
|
||||||
|
echo "# Adding translation groups to existing records" . "\n";
|
||||||
|
echo "#################################\n";
|
||||||
|
|
||||||
|
$allSiteTreeIDs = DB::query('SELECT "ID" FROM "SiteTree"')->column();
|
||||||
|
if($allSiteTreeIDs) foreach($allSiteTreeIDs as $id) {
|
||||||
|
$original = DataObject::get_by_id('SiteTree', $id);
|
||||||
|
$existingGroupID = $original->getTranslationGroup();
|
||||||
|
if(!$existingGroupID) $original->addTranslationGroup($original->ID);
|
||||||
|
$original->destroy();
|
||||||
|
unset($original);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataObject::flush_and_destroy_cache();
|
||||||
|
|
||||||
|
echo sprintf("Created translation groups for %d records\n", count($allSiteTreeIDs));
|
||||||
|
|
||||||
foreach(array('Stage', 'Live') as $stage) {
|
foreach(array('Stage', 'Live') as $stage) {
|
||||||
echo "<h2>Migrating stage $stage</h2>";
|
echo "\n\n#################################\n";
|
||||||
echo "<ul>";
|
echo "# Migrating stage $stage" . "\n";
|
||||||
|
echo "#################################\n";
|
||||||
|
|
||||||
$suffix = ($stage == 'Live') ? '_Live' : '';
|
$suffix = ($stage == 'Live') ? '_Live' : '';
|
||||||
|
|
||||||
// First get all entries in SiteTree_lang
|
// First get all entries in SiteTree_lang
|
||||||
// This should be all translated pages
|
// This should be all translated pages
|
||||||
$trans = DB::query('SELECT * FROM SiteTree_lang' . $suffix);
|
$trans = DB::query(sprintf('SELECT * FROM "_obsolete_SiteTree_lang%s"', $suffix));
|
||||||
|
|
||||||
// Iterate over each translated pages
|
// Iterate over each translated pages
|
||||||
foreach($trans as $oldtrans) {
|
foreach($trans as $oldtrans) {
|
||||||
echo "<li>Migrating $oldtrans[Lang] translation of " . Convert::raw2xml($oldtrans['Title']) . '</li>';
|
$newLocale = i18n::get_locale_from_lang($oldtrans['Lang']);
|
||||||
|
|
||||||
|
echo sprintf(
|
||||||
|
"Migrating from %s to %s translation of '%s' (#%d)\n",
|
||||||
|
$oldtrans['Lang'],
|
||||||
|
$newLocale,
|
||||||
|
Convert::raw2xml($oldtrans['Title']),
|
||||||
|
$oldtrans['OriginalLangID']
|
||||||
|
);
|
||||||
|
|
||||||
// Get the untranslated page
|
// Get the untranslated page
|
||||||
$original = Versioned::get_one_by_stage($oldtrans['ClassName'], $stage, '`SiteTree`.ID = ' . $oldtrans['OriginalLangID']);
|
|
||||||
|
$original = Versioned::get_one_by_stage(
|
||||||
|
$oldtrans['ClassName'],
|
||||||
|
$stage,
|
||||||
|
'"SiteTree"."ID" = ' . $oldtrans['OriginalLangID']
|
||||||
|
);
|
||||||
|
|
||||||
|
if(!$original) {
|
||||||
|
echo sprintf("Couldn't find original for #%d", $oldtrans['OriginalLangID']);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write locale to $original
|
||||||
|
$original->Locale = i18n::get_locale_from_lang(Translatable::default_lang());
|
||||||
|
$original->writeToStage($stage);
|
||||||
|
|
||||||
// Clone the original, and set it up as a translation
|
// Clone the original, and set it up as a translation
|
||||||
|
$existingTrans = $original->getTranslation($newLocale, $stage);
|
||||||
|
|
||||||
|
if($existingTrans) {
|
||||||
|
echo sprintf("Found existing new-style translation for #%d. Already merged? Skipping.\n", $oldtrans['OriginalLangID']);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doesn't work with stage/live split
|
||||||
|
//$newtrans = $original->createTranslation($newLocale);
|
||||||
|
|
||||||
$newtrans = $original->duplicate(false);
|
$newtrans = $original->duplicate(false);
|
||||||
$newtrans->OriginalID = $original->ID;
|
$newtrans->OriginalID = $original->ID;
|
||||||
// we have to "guess" a locale based on the language
|
// we have to "guess" a locale based on the language
|
||||||
$newtrans->Locale = i18n::get_locale_from_lang($oldtrans['Lang']);
|
$newtrans->Locale = $newLocale;
|
||||||
if($stage == 'Live' && array_key_exists($original->ID, $ids)) {
|
if($stage == 'Live' && array_key_exists($original->ID, $ids)) {
|
||||||
$newtrans->ID = $ids[$original->ID];
|
$newtrans->ID = $ids[$original->ID];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look at each class in the ancestry, and see if there is a _lang table for it
|
// Look at each class in the ancestry, and see if there is a _lang table for it
|
||||||
foreach(ClassInfo::ancestry($oldtrans['ClassName']) as $classname) {
|
foreach(ClassInfo::ancestry($oldtrans['ClassName']) as $classname) {
|
||||||
$oldtransitem = false;
|
$oldtransitem = false;
|
||||||
@ -52,34 +133,41 @@ class MigrateTranslatableTask extends BuildTask {
|
|||||||
if($classname == 'SiteTree') {
|
if($classname == 'SiteTree') {
|
||||||
$oldtransitem = $oldtrans;
|
$oldtransitem = $oldtrans;
|
||||||
} elseif(in_array(strtolower($classname) . '_lang', DB::tableList())) {
|
} elseif(in_array(strtolower($classname) . '_lang', DB::tableList())) {
|
||||||
$oldtransitem = DB::query('SELECT * FROM ' . $classname . '_lang' . $suffix . ' WHERE OriginalLangID = ' . $original->ID . ' AND Lang = \'' . $oldtrans['Lang'] . '\'')->first();
|
$oldtransitem = DB::query(sprintf(
|
||||||
|
'SELECT * FROM "_obsolete_%s_lang%s" WHERE "OriginalLangID" = %d AND "Lang" = \'%s\'',
|
||||||
|
$classname,
|
||||||
|
$suffix,
|
||||||
|
$original->ID,
|
||||||
|
$oldtrans['Lang']
|
||||||
|
))->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy each translated field into the new translation
|
// Copy each translated field into the new translation
|
||||||
if($oldtransitem) foreach($oldtransitem as $key => $value) {
|
if($oldtransitem) foreach($oldtransitem as $key => $value) {
|
||||||
if(!in_array($key, array('ID', 'OriginalLangID', 'ClassName'))) {
|
if(!in_array($key, array('ID', 'OriginalLangID'))) {
|
||||||
$newtrans->$key = $value;
|
$newtrans->$key = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Write the new translation to the database
|
// Write the new translation to the database
|
||||||
$sitelang = Translatable::current_locale();
|
$sitelang = Translatable::current_locale();
|
||||||
Translatable::set_reading_locale($newtrans->Locale);
|
Translatable::set_reading_locale($newtrans->Locale);
|
||||||
$newtrans->writeToStage($stage, true);
|
$newtrans->writeToStage($stage);
|
||||||
Translatable::set_reading_locale($sitelang);
|
Translatable::set_reading_locale($sitelang);
|
||||||
|
|
||||||
|
$newtrans->addTranslationGroup($original->getTranslationGroup(), true);
|
||||||
|
|
||||||
|
|
||||||
if($stage == 'Stage') {
|
if($stage == 'Stage') {
|
||||||
$ids[$original->ID] = $newtrans->ID;
|
$ids[$original->ID] = $newtrans->ID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
echo '</ul>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
echo '<strong>Done!</strong>';
|
echo "\n\n#################################\n";
|
||||||
|
echo "Done!\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user