PluginProbe ʕ •ᴥ•ʔ
Wp Social Login and Register Social Counter / 3.2.1
Wp Social Login and Register Social Counter v3.2.1
3.2.1 trunk 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.10 1.3.11 1.3.2 1.3.3 1.3.4 1.3.6 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.4 1.4.5 1.4.6 1.4.8 1.4.9 1.5.0 1.6.0 1.6.1 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.8.0 1.8.1 1.8.2 1.8.3 1.8.5 1.8.6 1.9.0 2.0.0 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.8 2.2.9 3.0.0 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0
wp-social / xs_migration / data-migration.php
wp-social / xs_migration Last commit date
markup 3 years ago data-migration.php 3 years ago migration-contract.php 5 years ago migration.php 3 years ago
data-migration.php
457 lines
1 <?php
2
3 namespace WP_Social\Xs_Migration;
4
5
6 /**
7 * Class Data_Migration
8 *
9 * @package WP_Social\Xs_Migration
10 */
11 abstract class Data_Migration implements Migration_Contract {
12
13 const STATUS_DONE = 'done';
14 const STATUS_QUEUED = 'queued';
15 const STATUS_RUNNING = 'running';
16
17 const STATUS_FINISHED = 'finished';
18 const STATUS_INITIATED = 'initiated';
19
20 const STATUS_METHOD_PAUSED = 'paused';
21 const STATUS_METHOD_EXECUTED = 'executed';
22 const STATUS_METHOD_EXECUTING = 'executing';
23
24 /**
25 * @param $txtDomain
26 * @param $versionFrom
27 * @param $versionTo
28 *
29 * @return mixed
30 */
31 public function input($txtDomain, $versionFrom, $versionTo) {
32
33 #$versionFrom = '1.1.9';
34 #$versionTo = '1.2.0';
35 $optionKey = 'data_migration_'.$txtDomain.'_log';
36
37 $from = str_replace('.', '_', trim($versionFrom));
38 $to = str_replace('.', '_', trim($versionTo));
39
40 $frm = $this->makeFullVersionKey($from);
41 $trm = $this->makeFullVersionKey($to);
42
43 $log = [];
44 $verCache = [];
45 $exPKey = $frm.'_'.$trm;
46
47 $verCache['o_from'] = $versionFrom;
48 $verCache['u_from'] = $from;
49 $verCache['p_from'] = $frm;
50 $verCache['o_to'] = $versionTo;
51 $verCache['u_to'] = $to;
52 $verCache['p_to'] = $trm;
53
54 $existingOption = get_option($optionKey);
55
56 if(!$existingOption) {
57
58 $existingOption = [];
59 $existingOption['status'] = self::STATUS_INITIATED;
60 $existingOption['plan_key'] = $exPKey;
61
62 $cStack = $this->getCallStacks([], $frm, $trm);
63
64 $existingOption['map'] = $cStack['map'];
65
66 $existingOption['execution_plan'][$exPKey]['status'] = self::STATUS_RUNNING;
67 $existingOption['execution_plan'][$exPKey]['stack'] = $cStack['stack'];
68 $existingOption['execution_plan'][$exPKey]['available'] = $cStack['func'];
69 $existingOption['execution_plan'][$exPKey]['executing'] = '';
70 $existingOption['execution_plan'][$exPKey]['executed'] = [];
71 $existingOption['execution_plan'][$exPKey]['failed'] = [];
72 $existingOption['execution_plan'][$exPKey]['progress'] = [];
73 $existingOption['execution_plan'][$exPKey]['log'] = [];
74 $existingOption['execution_plan'][$exPKey]['version'] = $verCache;
75
76 $existingOption['plan_log'][$exPKey] = 'Execution plan '.$exPKey. ' initiated at '.date('Y-m-d H:i:s'). ' .' . PHP_EOL;
77
78 $log[] = 'Conversion initiated for version '. $versionFrom .' to '. $versionTo. ' at '.date('Y-m-d H:i:s').'.';
79 $log[] = 'Execution plan prepared.';
80 $log[] = 'Execution plan saved into database.';
81
82
83 if(empty($existingOption['execution_plan'][$exPKey]['stack'])) {
84
85 $log[] = '- No Conversion method found for '. $versionFrom .' to '. $versionTo .'';
86 $log[] = '-- exiting....';
87 $log[] = 'Execution plan executed at '.date('Y-m-d H:i:s').'.';
88 $log[] = '----------------------------------------------------------';
89
90
91 $existingOption['execution_plan'][$exPKey]['status'] = self::STATUS_FINISHED;
92 $existingOption['execution_plan'][$exPKey]['log'] = $log;
93 $existingOption['plan_log'][$exPKey] .= 'Execution plan '.$exPKey. ' finished at '.date('Y-m-d H:i:s'). ' .' . PHP_EOL;
94 $existingOption['status'] = self::STATUS_FINISHED;
95
96 //update_option($optionKey, $existingOption);
97
98 return [
99 'status' => 'success',
100 'log' => $log,
101 ];
102 }
103
104 $curExecMethod = array_shift($existingOption['execution_plan'][$exPKey]['stack']);
105
106 $existingOption['execution_plan'][$exPKey]['executing'] = $curExecMethod;
107 $existingOption['execution_plan'][$exPKey]['progress'][$curExecMethod] = [
108 'status' => self::STATUS_QUEUED,
109 'check_list' => [],
110 ];
111
112
113 $log[] = 'Execution plan '.$exPKey.' has started at '.date('Y-m-d H:i:s').'.';
114 $log[] = '- Conversion method '. $curExecMethod . ' entered into queue at '.date('Y-m-d H:i:s').'.';
115 $log[] = '-- Method '.$curExecMethod.' is executing....';
116
117
118 $existingOption['execution_plan'][$exPKey]['log'] = $log;
119 $existingOption['execution_plan'][$exPKey]['log'][] = '-- ....';
120 $existingOption['execution_plan'][$exPKey]['progress'][$curExecMethod]['status'] = self::STATUS_METHOD_EXECUTING;
121
122 //update_option($optionKey, $existingOption);
123
124 return $this->$curExecMethod($optionKey, $exPKey, $existingOption);
125 //return $existingOption;
126 }
127
128 #We have reached this point,
129 #this means we do not have previously saved progress into database
130 #Now we are checking the status of the execution plan....
131
132 if($existingOption['status'] === self::STATUS_INITIATED) {
133
134 #this is the initiated plan key, it must be defined by the programmer when status is set to initiated.
135 $planKey = $existingOption['plan_key'];
136 $planStat = $existingOption['execution_plan'][$planKey]['status'];
137 $log = $existingOption['execution_plan'][$planKey]['log'];
138
139 if($planStat === self::STATUS_DONE) {
140
141 #the execution plan has been executed but some how the status of the migration status is not finished
142 #If a plan is done then migration status must be finished............................................
143 #So we will do nothing but change the migration status finished......................................
144 #though this should never happened...................................................................
145
146 $existingOption['status'] = self::STATUS_FINISHED;
147
148 $log[] = '-- ! Migration status is initiated but execution plan ' .$planKey. ' is finished. This is a potential bug, we are finishing the execution plan at '.date('Y-m-d H:i:s');
149 $log[] = '------------------------------------------------------------------------------';
150
151 $existingOption['execution_plan'][$planKey]['log'] = $log;
152
153 //update_option($optionKey, $existingOption);
154
155 return [
156 'status' => 'success',
157 'log' => $log,
158 ];
159 }
160
161 #Execution plan is not finished................
162 #We will execute all the methods from stack....
163 $mtdKey = $existingOption['execution_plan'][$planKey]['executing'];
164 $mtdStat = $existingOption['execution_plan'][$planKey]['progress'][$mtdKey]['status'];
165
166 if($mtdStat == self::STATUS_QUEUED || $mtdStat == self::STATUS_METHOD_PAUSED) {
167
168 $existingOption['execution_plan'][$planKey]['progress'][$mtdKey] = [
169 'status' => self::STATUS_METHOD_EXECUTING,
170 ];
171
172 //update_option($optionKey, $existingOption);
173
174 return $this->$mtdKey($optionKey, $planKey, $existingOption);
175 }
176
177 if($mtdStat == self::STATUS_METHOD_EXECUTING) {
178
179 #Someone initiated the method execution, so in this interval we will do nothing.
180 return $log;
181 }
182
183 if($mtdStat == self::STATUS_METHOD_EXECUTED) {
184
185 #the method we were executing and it was finished, now we will enter new method in execution queue.
186 #this method will enter into executed stack...................................................
187
188 $existingOption['execution_plan'][$planKey]['executed'][] = $mtdKey;
189 $existingOption['execution_plan'][$planKey]['executing'] = '';
190
191 if(empty($existingOption['execution_plan'][$planKey]['stack'])) {
192
193 #All the method from call stack has been executed
194 #Now we will finish the plan and the migration...
195
196 $existingOption['status'] = self::STATUS_FINISHED;
197 $existingOption['execution_plan'][$planKey]['status'] = self::STATUS_DONE;
198 //$existingOption['execution_plan'][$planKey]['version'] = $verCache;
199 $existingOption['plan_key'] = '';
200
201
202 $log[] = 'Conversion method '.$mtdKey.' has finished all its conversion and check list.';
203 $log[] = 'Calling stack is finished.';
204 $log[] = 'Execution plan executed and data conversion from '.$verCache['o_from']. ' to '.$verCache['o_to'].' at '.date('Y-m-d H:i:s').'.';
205 $log[] = '...................................................................................';
206
207 $existingOption['execution_plan'][$planKey]['log'] = $log;
208
209 //update_option($optionKey, $existingOption);
210
211 return [
212 'status' => 'success',
213 'log' => $log,
214 ];
215 }
216
217 #Call stack is not finished,
218 #So we will queued the next method from stack
219
220 $nx = array_pop($existingOption['execution_plan'][$planKey]['stack']);
221
222 $existingOption['execution_plan'][$planKey]['executing'] = $nx;
223
224 $existingOption['execution_plan'][$planKey]['progress'][$nx] = [
225 'status' => self::STATUS_METHOD_EXECUTING,
226 'check_list' => [],
227 ];
228
229 $log[] = '- Conversion method '. $nx . ' entered into queue at '.date('Y-m-d H:i:s').'.';
230 $log[] = '-- Method '. $nx. ' is executing...';
231
232 $existingOption['execution_plan'][$planKey]['log'] = $log;
233 $existingOption['execution_plan'][$planKey]['log'][] = '-- ....';
234
235 //update_option($optionKey, $existingOption);
236
237 return $this->$nx($optionKey, $planKey, $existingOption);
238 }
239
240 return [
241 'status' => 'error',
242 'log' => [
243 'Execution mtdStat error, method undefined.'
244 ],
245 ];
246 }
247
248 if($existingOption['status'] === self::STATUS_FINISHED) {
249
250 #In scenario could happen like someone initiated plan 001003003_001003004
251 #and now they want to migrate/initiate plan 001003004_001003005..........
252 #........................................................................
253
254 if(empty($existingOption['execution_plan'][$exPKey])) {
255
256 $existingOption['status'] = self::STATUS_INITIATED;
257 $existingOption['plan_key'] = $exPKey;
258
259 $cStack = $this->getCallStacks([], $frm, $trm);
260
261 $existingOption['map'] = $cStack['map'];
262
263 $existingOption['execution_plan'][$exPKey]['status'] = self::STATUS_RUNNING;
264 $existingOption['execution_plan'][$exPKey]['stack'] = $cStack['stack'];
265 $existingOption['execution_plan'][$exPKey]['available'] = $cStack['func'];
266 $existingOption['execution_plan'][$exPKey]['executing'] = '';
267 $existingOption['execution_plan'][$exPKey]['executed'] = [];
268 $existingOption['execution_plan'][$exPKey]['failed'] = [];
269 $existingOption['execution_plan'][$exPKey]['progress'] = [];
270 $existingOption['execution_plan'][$exPKey]['log'] = [];
271 $existingOption['execution_plan'][$exPKey]['version'] = $verCache;
272
273 $existingOption['plan_log'][$exPKey] = 'Execution plan '.$exPKey. ' initiated at '.date('Y-m-d H:i:s'). ' .' . PHP_EOL;
274
275 $log[] = 'Conversion initiated for version '. $versionFrom .' to '. $versionTo. ' at '.date('Y-m-d H:i:s').'.';
276 $log[] = 'Execution plan prepared.';
277 $log[] = 'Execution plan saved into database.';
278
279
280 if(empty($existingOption['execution_plan'][$exPKey]['stack'])) {
281
282 $log[] = '- No Conversion method found for '. $versionFrom .' to '. $versionTo .'';
283 $log[] = '-- exiting the execution plan....';
284 $log[] = 'Calling stack is finished.';
285 $log[] = 'Execution plan executed and data conversion from '.$versionFrom. ' to '.$versionTo.' at '.date('Y-m-d H:i:s').'.';
286 $log[] = '...................................................................................';
287
288 $existingOption['execution_plan'][$exPKey]['status'] = self::STATUS_FINISHED;
289 $existingOption['execution_plan'][$exPKey]['log'] = $log;
290 $existingOption['plan_log'][$exPKey] .= 'Execution plan '.$exPKey. ' finished at '.date('Y-m-d H:i:s'). ' .' . PHP_EOL;
291 $existingOption['status'] = self::STATUS_FINISHED;
292
293 //update_option($optionKey, $existingOption);
294
295 return [
296 'status' => 'success',
297 'log' => $log,
298 ];
299 }
300
301 $curExecMethod = array_shift($existingOption['execution_plan'][$exPKey]['stack']);
302
303 $existingOption['execution_plan'][$exPKey]['executing'] = $curExecMethod;
304 $existingOption['execution_plan'][$exPKey]['progress'][$curExecMethod] = [
305 'status' => self::STATUS_QUEUED,
306 'check_list' => [],
307 ];
308
309
310 $log[] = 'Execution plan '.$exPKey.' has started at '.date('Y-m-d H:i:s').'.';
311 $log[] = '- Conversion method '. $curExecMethod . ' entered into queue at '.date('Y-m-d H:i:s').'.';
312 $log[] = '-- Method '.$curExecMethod.' is executing....';
313
314 $existingOption['execution_plan'][$exPKey]['log'] = $log;
315 $existingOption['execution_plan'][$exPKey]['log'][] = '-- ....';
316 $existingOption['execution_plan'][$exPKey]['progress'][$curExecMethod]['status'] = self::STATUS_METHOD_EXECUTING;
317
318 //update_option($optionKey, $existingOption);
319
320 return $this->$curExecMethod($optionKey, $exPKey, $existingOption);
321 //return $existingOption;
322 }
323
324
325 #This is the scenario where migration status is finished
326 #and there are also configuration with execution plan
327 #.......................................................
328
329 #Now execution plan could be finished
330 #that means user already migrated version $from to $to [e.g 1.3.4 to 1.3.5]
331 #and they again trying to migrate same version to version
332 #..........................................................................
333 if($existingOption['execution_plan'][$exPKey]['status'] === self::STATUS_DONE) {
334
335 return [
336 'status' => 'success',
337 'log' => $existingOption['execution_plan'][$exPKey]['log'],
338 ];
339 }
340
341 #In no scenario this should happened, only when there is a mistake from programmer or corrupt data.
342
343 return [
344 'status' => 'error',
345 'log' => [
346 'Could not act on given request. Logical flow detected.'
347 ],
348 ];
349 }
350
351
352 return [
353 'status' => 'error',
354 'log' => [
355 'Exiting...data is corrupted.'
356 ],
357 ];
358 }
359
360
361 /**
362 *
363 * @param array $data
364 */
365 public function output(array $data) {
366
367 if(!empty($data['option'])) {
368
369 foreach($data['option'] as $opKey => $opVal) {
370
371 update_option($opKey, $opVal);
372 }
373 }
374 }
375
376
377 /**
378 *
379 * @param $versionMap
380 * @param $frm
381 * @param $trm
382 *
383 * @return array
384 */
385 private function getCallStacks($versionMap, $frm, $trm) {
386
387 $callStack = [];
388 $conversionMethods = [];
389 $methods = get_class_methods($this);
390
391 foreach($methods as $method) {
392
393 if(substr($method, 0, 13) === 'convert_from_') {
394
395 $conversionMethods[] = $method;
396
397 $tmp = str_replace('convert_from_', '', $method);
398 $tmp = explode('_to_', $tmp);
399
400 $vl = $this->makeFullVersionKey($tmp[0]);
401 $vh = $this->makeFullVersionKey($tmp[1]);
402
403 $versionMap[$vl] = $tmp[0];
404 $versionMap[$vh] = $tmp[1];
405 }
406 }
407
408
409 ksort($versionMap);
410
411 foreach($versionMap as $k => $v) {
412
413 if($k >= $frm && $k < $trm) {
414
415 $fnc = '';
416
417 foreach($conversionMethods as $conversionMethod) {
418
419 if(strpos($conversionMethod, 'convert_from_'.$v) !== false) {
420
421 $fnc = $conversionMethod;
422
423 break;
424 }
425 }
426
427 if(!empty($fnc)) {
428 $callStack[] = $fnc;
429 }
430 }
431 }
432
433 return [
434 'map' => $versionMap,
435 'func' => $conversionMethods,
436 'stack' => $callStack,
437 ];
438 }
439
440 /**
441 *
442 * @param $string
443 *
444 * @return string
445 */
446 public function makeFullVersionKey($string) {
447
448 $fr = explode('_', $string);
449
450 $frm = array_map(function($item){
451 return str_pad($item, 3, '0', STR_PAD_LEFT);
452 }, $fr);
453
454 return implode('', $frm);
455 }
456
457 }