Webylon 3.1 API Docs
  • Package
  • Class
  • Tree
  • Deprecated
  • Download
Version: current
  • 3.2
  • 3.1

Packages

  • auth
  • Booking
  • cart
    • shipping
    • steppedcheckout
  • Catalog
  • cms
    • assets
    • batchaction
    • batchactions
    • bulkloading
    • comments
    • content
    • core
    • export
    • newsletter
    • publishers
    • reports
    • security
    • tasks
  • Dashboard
  • DataObjectManager
  • event
  • faq
  • forms
    • actions
    • core
    • fields-basic
    • fields-dataless
    • fields-datetime
    • fields-files
    • fields-formatted
    • fields-formattedinput
    • fields-relational
    • fields-structural
    • transformations
    • validators
  • googlesitemaps
  • guestbook
  • installer
  • newsletter
  • None
  • photo
    • gallery
  • PHP
  • polls
  • recaptcha
  • sapphire
    • api
    • bulkloading
    • control
    • core
    • cron
    • dev
    • email
    • fields-formattedinput
    • filesystem
    • formatters
    • forms
    • i18n
    • integration
    • misc
    • model
    • parsers
    • search
    • security
    • tasks
    • testing
    • tools
    • validation
    • view
    • widgets
  • seo
    • open
      • graph
  • sfDateTimePlugin
  • spamprotection
  • stealth
    • captha
  • subsites
  • userform
    • pagetypes
  • userforms
  • webylon
  • widgets

Classes

  • EncryptAllPasswordsTask
  • i18nTextCollectorTask
  • MigrateSiteTreeLinkingTask
  • MigrateTranslatableTask
  • UpgradeSiteTreePermissionSchemaTask
  1 <?php
  2 /**
  3  * Migrates the old Translatable datamodel introduced in SilverStripe 2.1 to the new schema
  4  * introduced in SilverStripe 2.3.2.
  5  * Just works for {@link SiteTree} records and subclasses. If you have used the Translatable
  6  * extension on other {@link DataObject} subclasses before, this script won't migrate them automatically.
  7  * 
  8  * <h2>Limitations</h2>
  9  * 
 10  * - Information from the {@link Versioned} extension (e.g. in "SiteTree_versions" table)
 11  *   will be discarded for translated records.
 12  * - Custom translatable fields on your own {@link Page} class or subclasses thereof won't
 13  *   be migrated into the translation.
 14  * - 2.1-style subtags of a language (e.g. "en") will be automatically disambiguated to their full
 15  *   locale value (e.g. "en_US"), by the lookup defined in {@link i18n::get_locale_from_lang()}.
 16  * - Doesn't detect published translations when the script is run twice on the same data set
 17  * 
 18  * <h2>Usage</h2>
 19  * 
 20  * PLEASE BACK UP YOUR DATABASE BEFORE RUNNING THIS SCRIPT.
 21  * 
 22  * Warning: Please run dev/build on your 2.2 database to update the schema before running this task.
 23  * The dev/build command will rename tables like "SiteTree_lang" to "_obsolete_SiteTree_lang".
 24  *
 25  * <h3>Commandline</h3>
 26  * Requires "sake" tool (see http://doc.silverstripe.com/?id=sake)
 27  * <example>
 28  * sake dev/tasks/MigrateTranslatableTask
 29  * </example>
 30  *
 31  * <h3>Browser</h3>
 32  * <example>
 33  * http://mydomain.com/dev/tasks/MigrateTranslatableTask
 34  * </example>
 35  * 
 36  * @package sapphire
 37  * @subpackage tasks
 38  */
 39 class MigrateTranslatableTask extends BuildTask {
 40     protected $title = "Migrate Translatable Task";
 41     
 42     protected $description = "Migrates site translations from SilverStripe 2.1/2.2 to new database structure.";
 43     
 44     function init() {
 45         parent::init();
 46         
 47         $canAccess = (Director::isDev() || Director::is_cli() || Permission::check("ADMIN"));
 48         if(!$canAccess) return Security::permissionFailure($this);
 49     }
 50     
 51     function run($request) {
 52         $ids = array();
 53         
 54         echo "#################################\n";
 55         echo "# Adding translation groups to existing records" . "\n";
 56         echo "#################################\n";
 57         
 58         $allSiteTreeIDs = DB::query('SELECT "ID" FROM "SiteTree"')->column();
 59         if($allSiteTreeIDs) foreach($allSiteTreeIDs as $id) {
 60             $original = DataObject::get_by_id('SiteTree', $id);
 61             $existingGroupID = $original->getTranslationGroup();
 62             if(!$existingGroupID) $original->addTranslationGroup($original->ID);
 63             $original->destroy();
 64             unset($original);
 65         }
 66         
 67         DataObject::flush_and_destroy_cache();
 68         
 69         echo sprintf("Created translation groups for %d records\n", count($allSiteTreeIDs));
 70 
 71         foreach(array('Stage', 'Live') as $stage) {
 72             echo "\n\n#################################\n";
 73             echo "# Migrating stage $stage" . "\n";
 74             echo "#################################\n";
 75             
 76             $suffix = ($stage == 'Live') ? '_Live' : '';
 77         
 78             // First get all entries in SiteTree_lang
 79             // This should be all translated pages
 80             $trans = DB::query(sprintf('SELECT * FROM "_obsolete_SiteTree_lang%s"', $suffix));
 81         
 82             // Iterate over each translated pages
 83             foreach($trans as $oldtrans) {
 84                 $newLocale = i18n::get_locale_from_lang($oldtrans['Lang']);
 85                 
 86                 echo sprintf(
 87                     "Migrating from %s to %s translation of '%s' (#%d)\n", 
 88                     $oldtrans['Lang'],
 89                     $newLocale, 
 90                     Convert::raw2xml($oldtrans['Title']), 
 91                     $oldtrans['OriginalLangID']
 92                 );
 93             
 94                 // Get the untranslated page
 95                 
 96                 $original = Versioned::get_one_by_stage(
 97                     $oldtrans['ClassName'], 
 98                     $stage, 
 99                     '"SiteTree"."ID" = ' .  $oldtrans['OriginalLangID']
100                 );
101                 
102                 if(!$original) {
103                     echo sprintf("Couldn't find original for #%d", $oldtrans['OriginalLangID']);
104                     continue;
105                 }
106                 
107                 // write locale to $original
108                 $original->Locale = i18n::get_locale_from_lang(Translatable::default_lang());
109                 $original->writeToStage($stage);
110                 
111                 // Clone the original, and set it up as a translation
112                 $existingTrans = $original->getTranslation($newLocale, $stage);
113                 
114                 if($existingTrans) {
115                     echo sprintf("Found existing new-style translation for #%d. Already merged? Skipping.\n", $oldtrans['OriginalLangID']);
116                     continue;
117                 }
118                 
119                 // Doesn't work with stage/live split
120                 //$newtrans = $original->createTranslation($newLocale);
121                 
122                 $newtrans = $original->duplicate(false);
123                 $newtrans->OriginalID = $original->ID;
124                 // we have to "guess" a locale based on the language
125                 $newtrans->Locale = $newLocale;
126                 if($stage == 'Live' && array_key_exists($original->ID, $ids)) {
127                     $newtrans->ID = $ids[$original->ID];
128                 }
129                 
130                 // Look at each class in the ancestry, and see if there is a _lang table for it
131                 foreach(ClassInfo::ancestry($oldtrans['ClassName']) as $classname) {
132                     $oldtransitem = false;
133                 
134                     // If the class is SiteTree, we already have the DB record, else check for the table and get the record
135                     if($classname == 'SiteTree') {
136                         $oldtransitem = $oldtrans;
137                     } elseif(in_array(strtolower($classname) . '_lang', DB::tableList())) {
138                         $oldtransitem = DB::query(sprintf(
139                             'SELECT * FROM "_obsolete_%s_lang%s" WHERE "OriginalLangID" = %d AND "Lang" = \'%s\'',
140                             $classname,
141                             $suffix,
142                             $original->ID,
143                             $oldtrans['Lang']
144                         ))->first();
145                     }
146                 
147                     // Copy each translated field into the new translation
148                     if($oldtransitem) foreach($oldtransitem as $key => $value) {
149                         if(!in_array($key, array('ID', 'OriginalLangID'))) {
150                             $newtrans->$key = $value;
151                         }
152                     }
153             
154                 }
155 
156                 // Write the new translation to the database
157                 $sitelang = Translatable::get_current_locale();
158                 Translatable::set_current_locale($newtrans->Locale); 
159                 $newtrans->writeToStage($stage);
160                 Translatable::set_current_locale($sitelang);
161                 
162                 $newtrans->addTranslationGroup($original->getTranslationGroup(), true);
163 
164                 
165                 if($stage == 'Stage') {
166                     $ids[$original->ID] = $newtrans->ID;
167                 }
168             }
169         }
170         
171         echo "\n\n#################################\n";
172         echo "Done!\n";
173     }
174 }
175 
176 ?>
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -
Webylon 3.1 API Docs API documentation generated by ApiGen 2.8.0