PluginProbe ʕ •ᴥ•ʔ
ElementsKit Elementor Addons – Advanced Widgets & Templates Addons for Elementor / 4.0.2
ElementsKit Elementor Addons – Advanced Widgets & Templates Addons for Elementor v4.0.2
4.0.2 4.0.1 4.0.0 3.10.02 3.10.01 3.9.10 3.9.9 3.9.8 3.9.7 3.9.5 3.9.6 3.9.3 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.3.1 2.3.1.1 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.3.7 2.4.0 2.5.0 2.5.1 2.5.10 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.5 2.8.6 2.8.7 2.8.8 2.9.0 2.9.1 2.9.2 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.4.7 3.4.8 3.4.9 3.5.0 3.5.1 3.5.2 3.5.3 3.5.4 3.5.5 3.5.6 3.6.0 3.6.1 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.7.5 3.7.6 3.7.7 3.7.8 3.7.9 3.8.0 3.8.1 3.8.2 3.9.0 3.9.1 3.9.2 trunk 1.2.6 1.2.7 1.2.9 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.10 1.5.11 1.5.12 1.5.2 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.0.9.1 2.0.9.2 2.0.9.3
elementskit-lite / libs / xs-migration / data-migration.php
elementskit-lite / libs / xs-migration Last commit date
data-migration.php 2 years ago initiator.php 4 years ago migration-contract.php 4 years ago migration.php 2 years ago
data-migration.php
417 lines
1 <?php
2
3 namespace ElementsKit_Lite\Libs\Xs_Migration;
4
5 abstract class Data_Migration implements Migration_Contract {
6
7
8 const SUB_ROUTINE_STATUS_INCOMPLETE = '__incomplete';
9 const SUB_ROUTINE_STATUS_DONE = '__done';
10
11
12 const GENERIC_STATUS_YES = 'yes';
13 const GENERIC_STATUS_NO = 'no';
14
15 const STATUS_DONE = 'done';
16 const STATUS_QUEUED = 'queued';
17 const STATUS_RUNNING = 'running';
18
19 const STATUS_FINISHED = 'finished';
20 const STATUS_INITIATED = 'initiated';
21
22 const STATUS_METHOD_PAUSED = 'paused';
23 const STATUS_METHOD_EXECUTED = 'executed';
24 const STATUS_METHOD_EXECUTING = 'executing';
25
26 private $new_text_domain = 'elementskit-lite';
27 private $text_domain = 'elementskit-lite';
28 private $max_iteration = 10;
29
30
31 /**
32 * @param $txtDomain
33 * @param $versionFrom
34 * @param $versionTo
35 *
36 * @return mixed
37 */
38 public function input( $txtDomain, $versionFrom, $versionTo ) {
39
40 #$versionFrom = '1.1.9';
41 #$versionTo = '1.2.0';
42 $optionKey = 'data_migration_' . $txtDomain . '_log';
43
44 $from = str_replace( '.', '_', trim( $versionFrom ) );
45 $to = str_replace( '.', '_', trim( $versionTo ) );
46
47 $frm = $this->makeFullVersionKey( $from );
48 $trm = $this->makeFullVersionKey( $to );
49
50 $existingOption = get_option( $optionKey );
51
52 if ( empty( $existingOption ) ) {
53
54 $log = array();
55 $log[] = 'Migration never has been done for this domain.';
56 $log[] = 'Initiating migration for version ' . $versionFrom . ' to ' . $versionTo . ' at ' . gmdate( 'Y-m-d H:i:s' ) . ' .';
57 $log[] = 'Scanning migration file for conversion methods.';
58
59 $cStack = $this->getCallStacks( array(), $frm, $trm );
60
61 $fn = array();
62
63 foreach ( $cStack['stack'] as $item ) {
64
65 $fn[ $item ] = self::STATUS_QUEUED;
66 }
67
68 $log[] = 'Execution plan prepared.';
69 $log[] = 'Execution plan saved into database.';
70
71 $existingOption['_func'] = $fn;
72 $existingOption['_log'] = $log;
73 $existingOption['_status'] = self::STATUS_INITIATED;
74
75 update_option( $optionKey, $existingOption );
76
77 return array(
78 'status' => 'success',
79 'log' => $existingOption,
80 'log2' => $cStack,
81 );
82 }
83
84 /**
85 * Now we have something saved into database
86 * lets check the status first
87 *
88 */
89
90 if ( $existingOption['_status'] == self::STATUS_FINISHED ) {
91
92 $log = $existingOption['_log'];
93
94 /**
95 * Now we have to check up-to which version this migration is done
96 */
97
98 $up_to = $this->makeFullVersionKey( $existingOption['_last_version_scanned'] );
99
100 if ( $up_to < $trm ) {
101
102 /**
103 * New version released of this plugin
104 * check if anything new need to migrate
105 */
106
107 $cStack = $this->getCallStacks( array(), $frm, $trm );
108 $fn = $existingOption['_func'];
109
110 $log[] = 'A new version update detected.';
111 $log[] = 'Scanning for new migration method.';
112
113 $found = false;
114
115 foreach ( $cStack['stack'] as $item ) {
116
117 if ( isset( $fn[ $item ] ) ) {
118 continue;
119 }
120
121 $fn[ $item ] = self::STATUS_QUEUED;
122
123 $found = true;
124 }
125
126 if ( $found ) {
127
128 $log[] = 'New conversion method detected.';
129 $log[] = 'Preparing execution plan.';
130 $log[] = 'Execution plan saved into database.';
131
132 $existingOption['_func'] = $fn;
133 $existingOption['_log'] = $log;
134 $existingOption['_status'] = self::STATUS_INITIATED;
135
136 update_option( $optionKey, $existingOption );
137
138 return array(
139 'status' => 'success',
140 'log' => $existingOption,
141 'log2' => $cStack,
142 );
143
144 } else {
145
146 $log[] = 'No new conversion method detected.';
147 $log[] = 'Updating the migration plan as finished for version ' . $versionTo . ' at ' . gmdate( 'Y-m-d H:i:s' ) . '.';
148
149 $existingOption['_func'] = $fn;
150 $existingOption['_log'] = $log;
151 $existingOption['_status'] = self::STATUS_FINISHED;
152 $existingOption['_last_version_scanned'] = $versionTo;
153 $existingOption['_plan_up_to'] = $trm;
154
155 update_option( $optionKey, $existingOption );
156
157 return array(
158 'status' => 'success',
159 'log' => $existingOption,
160 'log2' => $cStack,
161 );
162 }
163 }
164
165 /**
166 * As status is finished and last scanned version is same as the current plugin version
167 * code execution should not come here
168 * If any case it come to this point we are updating the settings
169 */
170
171 $log[] = 'In no scenario, execution pointer should not come here [something is wrong...].';
172
173 $existingOption['_log'] = $log;
174 $existingOption['_last_version_scanned'] = $versionTo;
175 $existingOption['_plan_up_to'] = $trm;
176
177 update_option( $optionKey, $existingOption );
178
179 return array(
180 'status' => 'success',
181 'log' => $existingOption,
182 );
183 }
184
185 /**
186 * At this point status of the execution plan is not finished
187 * lets do the work
188 *
189 */
190 $curExecMethod = '';
191 $mtdStat = '';
192
193 foreach ( $existingOption['_func'] as $mtd => $stat ) {
194
195 if ( $stat == self::STATUS_METHOD_EXECUTED ) {
196 continue;
197 }
198
199 $curExecMethod = $mtd;
200 $mtdStat = $stat;
201
202 break;
203 }
204
205 if ( empty( $curExecMethod ) ) {
206
207 /**
208 * All methods has been executed
209 */
210
211 $log = $existingOption['_log'];
212
213 $log[] = 'All conversion method has been executed.';
214 $log[] = 'Setting the migration plan as finished for version ' . $versionTo . ' at ' . gmdate( 'Y-m-d H:i:s' ) . '.';
215
216 $existingOption['_log'] = $log;
217 $existingOption['_status'] = self::STATUS_FINISHED;
218 $existingOption['_last_version_scanned'] = $versionTo;
219 $existingOption['_plan_up_to'] = $trm;
220
221 update_option( $optionKey, $existingOption );
222
223 return array(
224 'status' => 'success',
225 'log' => $existingOption,
226 );
227 }
228
229 /**
230 * We have a conversion method to run whose status is not executed
231 *
232 */
233
234 if ( $mtdStat == self::STATUS_QUEUED ) {
235
236 $log = $existingOption['_log'];
237
238 $log[] = 'Conversion method ' . $curExecMethod . ' entered into queue at ' . gmdate( 'Y-m-d H:i:s' ) . '.';
239 $log[] = '- Conversion method ' . $curExecMethod . ' has entered into execution phase at ' . gmdate( 'Y-m-d H:i:s' );
240
241 $fn = $existingOption['_func'];
242
243 $fn[ $curExecMethod ] = self::STATUS_METHOD_EXECUTING;
244
245 $existingOption['_func'] = $fn;
246 $existingOption['_log'] = $log;
247
248 update_option( $optionKey, $existingOption );
249
250 return $this->$curExecMethod( $optionKey, $existingOption );
251 }
252
253 if ( $mtdStat == self::STATUS_METHOD_EXECUTING ) {
254
255 return array(
256 'status' => 'failed',
257 'msg' => 'Another person already initiated the execution.',
258 'log' => $existingOption['_log'],
259 );
260 }
261
262 if ( $mtdStat == self::STATUS_METHOD_PAUSED ) {
263
264 $log = $existingOption['_log'];
265
266 $log[] = '- Conversion method ' . $curExecMethod . ' has entered into executing phase at ' . gmdate( 'Y-m-d H:i:s' );
267
268 $fn = $existingOption['_func'];
269
270 $fn[ $curExecMethod ] = self::STATUS_METHOD_EXECUTING;
271
272 $existingOption['_func'] = $fn;
273 $existingOption['_log'] = $log;
274
275 update_option( $optionKey, $existingOption );
276
277 return $this->$curExecMethod( $optionKey, $existingOption );
278 }
279
280 /**
281 * This is the scenario that never ever should occur
282 */
283 return array(
284 'status' => 'failed',
285 'msg' => 'Overflow',
286 'log' => array(
287 'Exiting...data is corrupted.',
288 ),
289 );
290 }
291
292
293 /**
294 *
295 * @param array $data
296 */
297 public function output( array $data ) {
298
299 if ( ! empty( $data['option'] ) ) {
300
301 foreach ( $data['option'] as $opKey => $opVal ) {
302
303 update_option( $opKey, $opVal );
304 }
305 }
306 }
307
308
309 /**
310 *
311 * @param $versionMap
312 * @param $frm
313 * @param $trm
314 *
315 * @return array
316 */
317 private function getCallStacks( $versionMap, $frm, $trm ) {
318
319 $callStack = array();
320 $conversionMethods = array();
321 $methods = get_class_methods( $this );
322
323 foreach ( $methods as $method ) {
324
325 if ( substr( $method, 0, 13 ) === 'convert_from_' ) {
326
327 $conversionMethods[] = $method;
328
329 $tmp = str_replace( 'convert_from_', '', $method );
330 $tmp = explode( '_to_', $tmp );
331
332 $vl = $this->makeFullVersionKey( $tmp[0] );
333 $vh = $this->makeFullVersionKey( $tmp[1] );
334
335 $versionMap[ $vl ] = $tmp[0];
336 $versionMap[ $vh ] = $tmp[1];
337 }
338 }
339
340 ksort( $versionMap );
341
342 foreach ( $versionMap as $k => $v ) {
343
344 if ( $k >= $frm && $k < $trm ) {
345
346 $fnc = '';
347
348 foreach ( $conversionMethods as $conversionMethod ) {
349
350 if ( strpos( $conversionMethod, 'convert_from_' . $v ) !== false ) {
351
352 $fnc = $conversionMethod;
353
354 break;
355 }
356 }
357
358 if ( ! empty( $fnc ) ) {
359 $callStack[] = $fnc;
360 }
361 }
362 }
363
364 return array(
365 'map' => $versionMap,
366 'func' => $conversionMethods,
367 'stack' => $callStack,
368 );
369 }
370
371
372 /**
373 *
374 * @param $string
375 *
376 * @return string
377 */
378 public function makeFullVersionKey( $string ) {
379
380 $fr = explode( '_', $string );
381
382 $frm = array_map(
383 function( $item ) {
384 return str_pad( $item, 3, '0', STR_PAD_LEFT );
385 },
386 $fr
387 );
388
389 return implode( '', $frm );
390 }
391
392
393 /**
394 * @return string
395 */
396 public function getNewTextDomain() {
397 return $this->new_text_domain;
398 }
399
400
401 /**
402 * @return string
403 */
404 public function getTextDomain() {
405 return $this->text_domain;
406 }
407
408
409 /**
410 * @return int
411 */
412 public function getMaxIteration() {
413 return $this->max_iteration;
414 }
415
416 }
417