This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
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 translatable |
||
37 | */ |
||
38 | class MigrateTranslatableTask extends BuildTask |
||
39 | { |
||
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 | public function init() |
||
45 | { |
||
46 | parent::init(); |
||
47 | |||
48 | $canAccess = (Director::isDev() || Director::is_cli() || Permission::check("ADMIN")); |
||
49 | if (!$canAccess) { |
||
50 | return Security::permissionFailure($this); |
||
51 | } |
||
52 | } |
||
53 | |||
54 | public function run($request) |
||
55 | { |
||
56 | $ids = array(); |
||
57 | |||
58 | echo "#################################\n"; |
||
59 | echo "# Adding translation groups to existing records" . "\n"; |
||
60 | echo "#################################\n"; |
||
61 | |||
62 | $allSiteTreeIDs = DB::query('SELECT "ID" FROM "SiteTree"')->column(); |
||
63 | if ($allSiteTreeIDs) { |
||
64 | foreach ($allSiteTreeIDs as $id) { |
||
65 | $original = DataObject::get_by_id('SiteTree', $id); |
||
66 | $existingGroupID = $original->getTranslationGroup(); |
||
67 | if (!$existingGroupID) { |
||
68 | $original->addTranslationGroup($original->ID); |
||
69 | } |
||
70 | $original->destroy(); |
||
71 | unset($original); |
||
72 | } |
||
73 | } |
||
74 | |||
75 | DataObject::flush_and_destroy_cache(); |
||
76 | |||
77 | echo sprintf("Created translation groups for %d records\n", count($allSiteTreeIDs)); |
||
78 | |||
79 | foreach (array('Stage', 'Live') as $stage) { |
||
80 | echo "\n\n#################################\n"; |
||
81 | echo "# Migrating stage $stage" . "\n"; |
||
82 | echo "#################################\n"; |
||
83 | |||
84 | $suffix = ($stage == 'Live') ? '_Live' : ''; |
||
85 | |||
86 | // First get all entries in SiteTree_lang |
||
87 | // This should be all translated pages |
||
88 | $trans = DB::query(sprintf('SELECT * FROM "_obsolete_SiteTree_lang%s"', $suffix)); |
||
89 | |||
90 | // Iterate over each translated pages |
||
91 | foreach ($trans as $oldtrans) { |
||
92 | $newLocale = i18n::get_locale_from_lang($oldtrans['Lang']); |
||
93 | |||
94 | echo sprintf( |
||
95 | "Migrating from %s to %s translation of '%s' (#%d)\n", |
||
96 | $oldtrans['Lang'], |
||
97 | $newLocale, |
||
98 | Convert::raw2xml($oldtrans['Title']), |
||
99 | $oldtrans['OriginalLangID'] |
||
100 | ); |
||
101 | |||
102 | // Get the untranslated page |
||
103 | |||
104 | $original = Versioned::get_one_by_stage( |
||
105 | $oldtrans['ClassName'], |
||
106 | $stage, |
||
107 | '"SiteTree"."ID" = ' . $oldtrans['OriginalLangID'] |
||
108 | ); |
||
109 | |||
110 | if (!$original) { |
||
111 | echo sprintf("Couldn't find original for #%d", $oldtrans['OriginalLangID']); |
||
112 | continue; |
||
113 | } |
||
114 | |||
115 | // write locale to $original |
||
116 | $original->Locale = i18n::get_locale_from_lang(Translatable::default_lang()); |
||
0 ignored issues
–
show
|
|||
117 | $original->writeToStage($stage); |
||
118 | |||
119 | // Clone the original, and set it up as a translation |
||
120 | $existingTrans = $original->getTranslation($newLocale, $stage); |
||
121 | |||
122 | if ($existingTrans) { |
||
123 | echo sprintf( |
||
124 | "Found existing new-style translation for #%d. Already merged? Skipping.\n", |
||
125 | $oldtrans['OriginalLangID'] |
||
126 | ); |
||
127 | continue; |
||
128 | } |
||
129 | |||
130 | // Doesn't work with stage/live split |
||
131 | //$newtrans = $original->createTranslation($newLocale); |
||
132 | |||
133 | $newtrans = $original->duplicate(false); |
||
134 | $newtrans->OriginalID = $original->ID; |
||
135 | // we have to "guess" a locale based on the language |
||
136 | $newtrans->Locale = $newLocale; |
||
137 | if ($stage == 'Live' && array_key_exists($original->ID, $ids)) { |
||
138 | $newtrans->ID = $ids[$original->ID]; |
||
139 | } |
||
140 | |||
141 | // Look at each class in the ancestry, and see if there is a _lang table for it |
||
142 | foreach (ClassInfo::ancestry($oldtrans['ClassName']) as $classname) { |
||
143 | $oldtransitem = false; |
||
144 | |||
145 | // If the class is SiteTree, we already have the DB record, |
||
146 | // else check for the table and get the record |
||
147 | if ($classname == 'SiteTree') { |
||
148 | $oldtransitem = $oldtrans; |
||
149 | } elseif (in_array(strtolower($classname) . '_lang', DB::tableList())) { |
||
150 | $oldtransitem = DB::query(sprintf( |
||
151 | 'SELECT * FROM "_obsolete_%s_lang%s" WHERE "OriginalLangID" = %d AND "Lang" = \'%s\'', |
||
152 | $classname, |
||
153 | $suffix, |
||
154 | $original->ID, |
||
155 | $oldtrans['Lang'] |
||
156 | ))->first(); |
||
157 | } |
||
158 | |||
159 | // Copy each translated field into the new translation |
||
160 | if ($oldtransitem) { |
||
161 | foreach ($oldtransitem as $key => $value) { |
||
162 | if (!in_array($key, array('ID', 'OriginalLangID'))) { |
||
163 | $newtrans->$key = $value; |
||
164 | } |
||
165 | } |
||
166 | } |
||
167 | } |
||
168 | |||
169 | // Write the new translation to the database |
||
170 | $sitelang = Translatable::get_current_locale(); |
||
171 | Translatable::set_current_locale($newtrans->Locale); |
||
172 | $newtrans->writeToStage($stage); |
||
173 | Translatable::set_current_locale($sitelang); |
||
174 | |||
175 | $newtrans->addTranslationGroup($original->getTranslationGroup(), true); |
||
176 | |||
177 | |||
178 | if ($stage == 'Stage') { |
||
179 | $ids[$original->ID] = $newtrans->ID; |
||
180 | } |
||
181 | } |
||
182 | } |
||
183 | |||
184 | echo "\n\n#################################\n"; |
||
185 | echo "Done!\n"; |
||
186 | } |
||
187 | } |
||
188 |
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.