diff --git a/tasks/MigrateTranslatableTask.php b/tasks/MigrateTranslatableTask.php
index 988123d9e..ee6d33839 100644
--- a/tasks/MigrateTranslatableTask.php
+++ b/tasks/MigrateTranslatableTask.php
@@ -1,5 +1,38 @@
Limitations
+ *
+ * - 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
+ *
+ *
Usage
+ *
+ * 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".
+ *
+ * Commandline
+ * Requires "sake" tool (see http://doc.silverstripe.com/?id=sake)
+ *
+ * sake dev/tasks/MigrateTranslatableTask
+ *
+ *
+ * Browser
+ *
+ * http://mydomain.com/dev/tasks/MigrateTranslatableTask
+ *
+ *
* @package sapphire
* @subpackage tasks
*/
@@ -16,34 +49,82 @@ class MigrateTranslatableTask extends BuildTask {
function run($request) {
$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) {
- echo "Migrating stage $stage
";
- echo "";
+ echo "\n\n#################################\n";
+ echo "# Migrating stage $stage" . "\n";
+ echo "#################################\n";
$suffix = ($stage == 'Live') ? '_Live' : '';
// First get all entries in SiteTree_lang
// 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
foreach($trans as $oldtrans) {
- echo "- Migrating $oldtrans[Lang] translation of " . Convert::raw2xml($oldtrans['Title']) . '
';
+ $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
- $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
+ $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->OriginalID = $original->ID;
// 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)) {
$newtrans->ID = $ids[$original->ID];
}
-
+
// Look at each class in the ancestry, and see if there is a _lang table for it
foreach(ClassInfo::ancestry($oldtrans['ClassName']) as $classname) {
$oldtransitem = false;
@@ -52,34 +133,41 @@ class MigrateTranslatableTask extends BuildTask {
if($classname == 'SiteTree') {
$oldtransitem = $oldtrans;
} 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
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;
}
}
}
-
-
+
// Write the new translation to the database
$sitelang = Translatable::current_locale();
Translatable::set_reading_locale($newtrans->Locale);
- $newtrans->writeToStage($stage, true);
+ $newtrans->writeToStage($stage);
Translatable::set_reading_locale($sitelang);
+ $newtrans->addTranslationGroup($original->getTranslationGroup(), true);
+
+
if($stage == 'Stage') {
$ids[$original->ID] = $newtrans->ID;
}
}
-
- echo '
';
}
- echo 'Done!';
+ echo "\n\n#################################\n";
+ echo "Done!\n";
}
}