PATH:
home
/
lab2454c
/
crypthorize.net
/
wp-content
/
plugins
/
elementskit-lite
/
libs
/
xs-migration
<?php namespace ElementsKit_Lite\Libs\Xs_Migration; abstract class Data_Migration implements Migration_Contract { const SUB_ROUTINE_STATUS_INCOMPLETE = '__incomplete'; const SUB_ROUTINE_STATUS_DONE = '__done'; const GENERIC_STATUS_YES = 'yes'; const GENERIC_STATUS_NO = 'no'; const STATUS_DONE = 'done'; const STATUS_QUEUED = 'queued'; const STATUS_RUNNING = 'running'; const STATUS_FINISHED = 'finished'; const STATUS_INITIATED = 'initiated'; const STATUS_METHOD_PAUSED = 'paused'; const STATUS_METHOD_EXECUTED = 'executed'; const STATUS_METHOD_EXECUTING = 'executing'; private $new_text_domain = 'elementskit-lite'; private $text_domain = 'elementskit-lite'; private $max_iteration = 10; /** * @param $txtDomain * @param $versionFrom * @param $versionTo * * @return mixed */ public function input($txtDomain, $versionFrom, $versionTo) { #$versionFrom = '1.1.9'; #$versionTo = '1.2.0'; $optionKey = 'data_migration_' . $txtDomain . '_log'; $from = str_replace('.', '_', trim($versionFrom)); $to = str_replace('.', '_', trim($versionTo)); $frm = $this->makeFullVersionKey($from); $trm = $this->makeFullVersionKey($to); $existingOption = get_option($optionKey); if(empty($existingOption)) { $log = []; $log[] = 'Migration never has been done for this domain.'; $log[] = 'Initiating migration for version ' . $versionFrom . ' to ' . $versionTo . ' at ' . date('Y-m-d H:i:s') . ' .'; $log[] = 'Scanning migration file for conversion methods.'; $cStack = $this->getCallStacks([], $frm, $trm); $fn = []; foreach($cStack['stack'] as $item) { $fn[$item] = self::STATUS_QUEUED; } $log[] = 'Execution plan prepared.'; $log[] = 'Execution plan saved into database.'; $existingOption['_func'] = $fn; $existingOption['_log'] = $log; $existingOption['_status'] = self::STATUS_INITIATED; update_option($optionKey, $existingOption); return [ 'status' => 'success', 'log' => $existingOption, 'log2' => $cStack, ]; } /** * Now we have something saved into database * lets check the status first * */ if($existingOption['_status'] == self::STATUS_FINISHED) { $log = $existingOption['_log']; /** * Now we have to check up-to which version this migration is done */ $up_to = $this->makeFullVersionKey($existingOption['_last_version_scanned']); if($up_to < $trm) { /** * New version released of this plugin * check if anything new need to migrate */ $cStack = $this->getCallStacks([], $frm, $trm); $fn = $existingOption['_func']; $log[] = 'A new version update detected.'; $log[] = 'Scanning for new migration method.'; $found = false; foreach($cStack['stack'] as $item) { if(isset($fn[$item])) { continue; } $fn[$item] = self::STATUS_QUEUED; $found = true; } if($found) { $log[] = 'New conversion method detected.'; $log[] = 'Preparing execution plan.'; $log[] = 'Execution plan saved into database.'; $existingOption['_func'] = $fn; $existingOption['_log'] = $log; $existingOption['_status'] = self::STATUS_INITIATED; update_option($optionKey, $existingOption); return [ 'status' => 'success', 'log' => $existingOption, 'log2' => $cStack, ]; } else { $log[] = 'No new conversion method detected.'; $log[] = 'Updating the migration plan as finished for version ' . $versionTo . ' at ' . date('Y-m-d H:i:s') . '.'; $existingOption['_func'] = $fn; $existingOption['_log'] = $log; $existingOption['_status'] = self::STATUS_FINISHED; $existingOption['_last_version_scanned'] = $versionTo; $existingOption['_plan_up_to'] = $trm; update_option($optionKey, $existingOption); return [ 'status' => 'success', 'log' => $existingOption, 'log2' => $cStack, ]; } } /** * As status is finished and last scanned version is same as the current plugin version * code execution should not come here * If any case it come to this point we are updating the settings */ $log[] = 'In no scenario, execution pointer should not come here [something is wrong...].'; $existingOption['_log'] = $log; $existingOption['_last_version_scanned'] = $versionTo; $existingOption['_plan_up_to'] = $trm; update_option($optionKey, $existingOption); return [ 'status' => 'success', 'log' => $existingOption, ]; } /** * At this point status of the execution plan is not finished * lets do the work * */ $curExecMethod = ''; $mtdStat = ''; foreach($existingOption['_func'] as $mtd => $stat) { if($stat == self::STATUS_METHOD_EXECUTED) { continue; } $curExecMethod = $mtd; $mtdStat = $stat; break; } if(empty($curExecMethod)) { /** * All methods has been executed */ $log = $existingOption['_log']; $log[] = 'All conversion method has been executed.'; $log[] = 'Setting the migration plan as finished for version ' . $versionTo . ' at ' . date('Y-m-d H:i:s') . '.'; $existingOption['_log'] = $log; $existingOption['_status'] = self::STATUS_FINISHED; $existingOption['_last_version_scanned'] = $versionTo; $existingOption['_plan_up_to'] = $trm; update_option($optionKey, $existingOption); return [ 'status' => 'success', 'log' => $existingOption, ]; } /** * We have a conversion method to run whose status is not executed * */ if($mtdStat == self::STATUS_QUEUED) { $log = $existingOption['_log']; $log[] = 'Conversion method ' . $curExecMethod . ' entered into queue at ' . date('Y-m-d H:i:s') . '.'; $log[] = '- Conversion method ' . $curExecMethod . ' has entered into execution phase at ' . date('Y-m-d H:i:s'); $fn = $existingOption['_func']; $fn[$curExecMethod] = self::STATUS_METHOD_EXECUTING; $existingOption['_func'] = $fn; $existingOption['_log'] = $log; update_option($optionKey, $existingOption); return $this->$curExecMethod($optionKey, $existingOption); } if($mtdStat == self::STATUS_METHOD_EXECUTING) { return [ 'status' => 'failed', 'msg' => 'Another person already initiated the execution.', 'log' => $existingOption['_log'], ]; } if($mtdStat == self::STATUS_METHOD_PAUSED) { $log = $existingOption['_log']; $log[] = '- Conversion method ' . $curExecMethod . ' has entered into executing phase at ' . date('Y-m-d H:i:s'); $fn = $existingOption['_func']; $fn[$curExecMethod] = self::STATUS_METHOD_EXECUTING; $existingOption['_func'] = $fn; $existingOption['_log'] = $log; update_option($optionKey, $existingOption); return $this->$curExecMethod($optionKey, $existingOption); } /** * This is the scenario that never ever should occur */ return [ 'status' => 'failed', 'msg' => 'Overflow', 'log' => [ 'Exiting...data is corrupted.', ], ]; } /** * * @param array $data */ public function output(array $data) { if(!empty($data['option'])) { foreach($data['option'] as $opKey => $opVal) { update_option($opKey, $opVal); } } } /** * * @param $versionMap * @param $frm * @param $trm * * @return array */ private function getCallStacks($versionMap, $frm, $trm) { $callStack = []; $conversionMethods = []; $methods = get_class_methods($this); foreach($methods as $method) { if(substr($method, 0, 13) === 'convert_from_') { $conversionMethods[] = $method; $tmp = str_replace('convert_from_', '', $method); $tmp = explode('_to_', $tmp); $vl = $this->makeFullVersionKey($tmp[0]); $vh = $this->makeFullVersionKey($tmp[1]); $versionMap[$vl] = $tmp[0]; $versionMap[$vh] = $tmp[1]; } } ksort($versionMap); foreach($versionMap as $k => $v) { if($k >= $frm && $k < $trm) { $fnc = ''; foreach($conversionMethods as $conversionMethod) { if(strpos($conversionMethod, 'convert_from_' . $v) !== false) { $fnc = $conversionMethod; break; } } if(!empty($fnc)) { $callStack[] = $fnc; } } } return [ 'map' => $versionMap, 'func' => $conversionMethods, 'stack' => $callStack, ]; } /** * * @param $string * * @return string */ public function makeFullVersionKey($string) { $fr = explode('_', $string); $frm = array_map(function($item) { return str_pad($item, 3, '0', STR_PAD_LEFT); }, $fr); return implode('', $frm); } /** * @return string */ public function getNewTextDomain() { return $this->new_text_domain; } /** * @return string */ public function getTextDomain() { return $this->text_domain; } /** * @return int */ public function getMaxIteration() { return $this->max_iteration; } }
[-] migration.php
[edit]
[+]
..
[-] data-migration.php
[edit]
[-] migration-contract.php
[edit]
[-] initiator.php
[edit]