forked from LiveCarta/LiveCartaWP
Changed source root directory
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Standard: PSR-2
|
||||
*
|
||||
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
|
||||
*
|
||||
* @package SC\DUPX\Chunk
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Event iterator
|
||||
*/
|
||||
interface EventIterator extends Iterator
|
||||
{
|
||||
/**
|
||||
* The callback accept 3 params
|
||||
* $event , $index and $current values
|
||||
*
|
||||
* @param null | callable $callback
|
||||
*/
|
||||
public function setEventCallback($callback = null);
|
||||
|
||||
/**
|
||||
* Execute event
|
||||
*
|
||||
* @param mixed $event
|
||||
* @param mixed $key
|
||||
* @param mixed $current
|
||||
*/
|
||||
public function doEvent($event, $key, $current);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Standard: PSR-2
|
||||
*
|
||||
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
|
||||
*
|
||||
* @package SC\DUPX\Chunk
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author andrea
|
||||
*/
|
||||
interface GenericSeekableIterator extends Iterator
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param mixed $position
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function gSeek($position);
|
||||
|
||||
/**
|
||||
* return current position
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPosition();
|
||||
|
||||
/**
|
||||
* Free resources in current iteration
|
||||
*/
|
||||
public function stopIteration();
|
||||
|
||||
/**
|
||||
* Return iterations count
|
||||
*/
|
||||
public function itCount();
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Step 3 iterator
|
||||
*
|
||||
* Standard: PSR-2
|
||||
*
|
||||
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
|
||||
*
|
||||
* @package SC\DUPX\Chunk
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
||||
|
||||
use Duplicator\Installer\Utils\Log\Log;
|
||||
|
||||
require_once(DUPX_INIT . '/classes/chunk/Iterators/Interfaces/GenericSeekableIterator.php');
|
||||
|
||||
/**
|
||||
* Description of class
|
||||
*
|
||||
* @author andrea
|
||||
*/
|
||||
class DUPX_s3_iterator implements GenericSeekableIterator
|
||||
{
|
||||
const STEP_START = 'start';
|
||||
const STEP_CLEANUP_EXTREA = 'cleanup_extra';
|
||||
const STEP_CLEANUP_PACKAGES = 'cleanup_packages';
|
||||
const STEP_CLEANUP_OPTIONS = 'cleanup_trans';
|
||||
const STEP_SEARCH_AND_REPLACE_INIT = 'init';
|
||||
const STEP_SEARCH_AND_REPLACE = 'search_replace';
|
||||
const STEP_REMOVE_MAINTENACE = 'rem_maintenance';
|
||||
const STEP_CREATE_ADMIN = 'create_admin';
|
||||
const STEP_CONF_UPDATE = 'config_update';
|
||||
const STEP_GEN_UPD = 'gen_update';
|
||||
const STEP_GEN_CLEAN = 'gen_clean';
|
||||
const STEP_NOTICE_TEST = 'notice_test';
|
||||
const STEP_CLEANUP_TMP_FILES = 'cleanup_tmp_files';
|
||||
const STEP_SET_FILE_PERMS = 'set_files_perms';
|
||||
const STEP_FINAL_REPORT_NOTICES = 'final_report';
|
||||
|
||||
private static $numIterations = 10;
|
||||
protected $position = array(
|
||||
'l0' => self::STEP_SEARCH_AND_REPLACE_INIT,
|
||||
'l1' => null,
|
||||
'l2' => null
|
||||
);
|
||||
protected $isValid = true;
|
||||
protected $tablesIterator = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$tables = DUPX_DB_Tables::getInstance()->getReplaceTablesNames();
|
||||
$this->tablesIterator = new ArrayIterator($tables);
|
||||
$this->rewind();
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
{
|
||||
$this->isValid = true;
|
||||
$this->position = array(
|
||||
'l0' => self::STEP_START,
|
||||
'l1' => null,
|
||||
'l2' => null
|
||||
);
|
||||
$this->tablesIterator->rewind();
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next()
|
||||
{
|
||||
switch ($this->position['l0']) {
|
||||
case self::STEP_START:
|
||||
$this->position['l0'] = self::STEP_CLEANUP_OPTIONS;
|
||||
break;
|
||||
case self::STEP_CLEANUP_OPTIONS:
|
||||
$this->position['l0'] = self::STEP_CLEANUP_EXTREA;
|
||||
break;
|
||||
case self::STEP_CLEANUP_EXTREA:
|
||||
$this->position['l0'] = self::STEP_CLEANUP_PACKAGES;
|
||||
break;
|
||||
case self::STEP_CLEANUP_PACKAGES:
|
||||
$this->position['l0'] = self::STEP_SEARCH_AND_REPLACE_INIT;
|
||||
break;
|
||||
case self::STEP_SEARCH_AND_REPLACE_INIT:
|
||||
if ($this->getNextSearchReplacePosition(true)) {
|
||||
// if search and replace is valid go to STEP_SEARCH_AND_REPLACE
|
||||
$this->position['l0'] = self::STEP_SEARCH_AND_REPLACE;
|
||||
} else {
|
||||
// if search and replace isn't valid skip STEP_SEARCH_AND_REPLACE and go to STEP_REMOVE_MAINTENACE
|
||||
$this->position['l0'] = self::STEP_REMOVE_MAINTENACE;
|
||||
}
|
||||
break;
|
||||
case self::STEP_SEARCH_AND_REPLACE:
|
||||
if (!$this->getNextSearchReplacePosition()) {
|
||||
$this->position['l0'] = self::STEP_REMOVE_MAINTENACE;
|
||||
}
|
||||
break;
|
||||
case self::STEP_REMOVE_MAINTENACE:
|
||||
$this->position['l0'] = self::STEP_CONF_UPDATE;
|
||||
break;
|
||||
case self::STEP_CONF_UPDATE:
|
||||
$this->position['l0'] = self::STEP_GEN_UPD;
|
||||
break;
|
||||
case self::STEP_GEN_UPD:
|
||||
$this->position['l0'] = self::STEP_GEN_CLEAN;
|
||||
break;
|
||||
case self::STEP_GEN_CLEAN:
|
||||
$this->position['l0'] = self::STEP_CREATE_ADMIN;
|
||||
break;
|
||||
case self::STEP_CREATE_ADMIN:
|
||||
$this->position['l0'] = self::STEP_NOTICE_TEST;
|
||||
break;
|
||||
case self::STEP_NOTICE_TEST:
|
||||
$this->position['l0'] = self::STEP_CLEANUP_TMP_FILES;
|
||||
break;
|
||||
case self::STEP_CLEANUP_TMP_FILES:
|
||||
$this->position['l0'] = self::STEP_SET_FILE_PERMS;
|
||||
break;
|
||||
case self::STEP_SET_FILE_PERMS:
|
||||
$this->position['l0'] = self::STEP_FINAL_REPORT_NOTICES;
|
||||
break;
|
||||
case self::STEP_FINAL_REPORT_NOTICES:
|
||||
default:
|
||||
$this->position['l0'] = null;
|
||||
$this->isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
private function getNextSearchReplacePosition($init = false)
|
||||
{
|
||||
$valid = true;
|
||||
$s3func = DUPX_S3_Funcs::getInstance();
|
||||
$pages = isset($s3func->cTableParams['pages']) ? $s3func->cTableParams['pages'] : 0;
|
||||
$this->position['l2'] = (int) $this->position['l2'];
|
||||
|
||||
$this->position['l2']++;
|
||||
if ($this->position['l2'] < $pages) {
|
||||
/* NEXT PAGE */
|
||||
Log::info('ITERATOR INCREMENT PAGE: ' . $this->position['l2'] . ' PAGES[' . $pages . ']', 3);
|
||||
$s3func->cTableParams['page'] = $this->position['l2'];
|
||||
} else {
|
||||
if ($init) {
|
||||
DUPX_UpdateEngine::loadInit();
|
||||
Log::info('ITERATOR FIRST TABLE: ' . $this->position['l2'] . ' PAGES[' . $pages . ']', 3);
|
||||
$this->tablesIterator->rewind();
|
||||
} else {
|
||||
Log::info('ITERATOR INCREMENT TABLE: ' . $this->position['l2'] . ' PAGES[' . $pages . ']', 3);
|
||||
if ($s3func->cTableParams['updated']) {
|
||||
$s3func->report['updt_tables']++;
|
||||
}
|
||||
$this->tablesIterator->next();
|
||||
}
|
||||
$this->position['l1'] = $this->tablesIterator->key();
|
||||
$this->position['l2'] = 0;
|
||||
|
||||
// search first table with rows and columns
|
||||
while ($this->tablesIterator->valid()) {
|
||||
Log::info('ITERATOR CHECK TABLE: ' . $this->tablesIterator->current(), 3);
|
||||
// init table params if isn't initialized
|
||||
if (DUPX_UpdateEngine::initTableParams($this->tablesIterator->current())) {
|
||||
// table with columns and rows found
|
||||
break;
|
||||
}
|
||||
// NEXT TABLE
|
||||
$this->tablesIterator->next();
|
||||
}
|
||||
|
||||
if ($this->tablesIterator->valid()) {
|
||||
$this->position['l1'] = $this->tablesIterator->key();
|
||||
$this->position['l2'] = 0;
|
||||
} else {
|
||||
$this->position['l1'] = null;
|
||||
$this->position['l2'] = null;
|
||||
$s3func->cTableParams = null;
|
||||
DUPX_UpdateEngine::loadEnd();
|
||||
DUPX_UpdateEngine::logStats();
|
||||
DUPX_UpdateEngine::logErrors();
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
return $valid;
|
||||
}
|
||||
|
||||
public function gSeek($position)
|
||||
{
|
||||
$this->position = $position;
|
||||
switch ($this->position['l0']) {
|
||||
case self::STEP_SEARCH_AND_REPLACE:
|
||||
$this->tablesIterator->seek($this->position['l1']);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
public function getPosition()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
{
|
||||
return implode('_', $this->position);
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
$result = array(
|
||||
'l0' => $this->position['l0'],
|
||||
'l1' => null,
|
||||
'l2' => null
|
||||
);
|
||||
$result['l0'] = $this->position['l0'];
|
||||
|
||||
switch ($this->position['l0']) {
|
||||
case self::STEP_SEARCH_AND_REPLACE:
|
||||
$result['l1'] = $this->tablesIterator->current();
|
||||
$result['l2'] = $this->position['l2'];
|
||||
break;
|
||||
default:
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function stopIteration()
|
||||
{
|
||||
switch ($this->position['l0']) {
|
||||
case self::STEP_SEARCH_AND_REPLACE:
|
||||
DUPX_UpdateEngine::commitAndSave();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function valid()
|
||||
{
|
||||
return $this->isValid;
|
||||
}
|
||||
|
||||
public function itCount()
|
||||
{
|
||||
return self::$numIterations;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chunk manager step 3
|
||||
*
|
||||
* Standard: PSR-2
|
||||
*
|
||||
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
|
||||
*
|
||||
* @package SC\DUPX\Chunk
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
||||
|
||||
use Duplicator\Installer\Core\Deploy\Database\DbCleanup;
|
||||
use Duplicator\Installer\Utils\Log\Log;
|
||||
use Duplicator\Installer\Utils\Log\LogHandler;
|
||||
use Duplicator\Libs\Snap\SnapJson;
|
||||
|
||||
require_once(DUPX_INIT . '/classes/chunk/class.chunkingmanager_file.php');
|
||||
require_once(DUPX_INIT . '/classes/chunk/Iterators/class.s3.iterator.php');
|
||||
|
||||
/**
|
||||
* Chunk manager step 3
|
||||
*
|
||||
* @author andrea
|
||||
*/
|
||||
class DUPX_chunkS3Manager extends DUPX_ChunkingManager_file
|
||||
{
|
||||
/**
|
||||
* Exectute action for every iteration
|
||||
*
|
||||
* @param string $key
|
||||
* @param array $current
|
||||
*/
|
||||
protected function action($key, $current)
|
||||
{
|
||||
$s3FuncsManager = DUPX_S3_Funcs::getInstance();
|
||||
|
||||
Log::info('CHUNK ACTION: CURRENT [' . implode('][', $current) . ']');
|
||||
|
||||
switch ($current['l0']) {
|
||||
case DUPX_s3_iterator::STEP_START:
|
||||
$s3FuncsManager->initLog();
|
||||
$s3FuncsManager->initChunkLog($this->maxIteration, $this->timeOut, $this->throttling, $GLOBALS['DATABASE_PAGE_SIZE']);
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_CLEANUP_OPTIONS:
|
||||
DbCleanup::cleanupOptions();
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_CLEANUP_EXTREA:
|
||||
DbCleanup::cleanupExtra();
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_CLEANUP_PACKAGES:
|
||||
DbCleanup::cleanupPackages();
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_SEARCH_AND_REPLACE_INIT:
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_SEARCH_AND_REPLACE:
|
||||
DUPX_UpdateEngine::evaluateTableRows($current['l1'], $current['l2']);
|
||||
DUPX_UpdateEngine::commitAndSave();
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_REMOVE_MAINTENACE:
|
||||
$s3FuncsManager->removeMaintenanceMode();
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_CREATE_ADMIN:
|
||||
$s3FuncsManager->createNewAdminUser();
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_CONF_UPDATE:
|
||||
$s3FuncsManager->configFilesUpdate();
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_GEN_UPD:
|
||||
$s3FuncsManager->generalUpdate();
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_GEN_CLEAN:
|
||||
$s3FuncsManager->generalCleanup();
|
||||
$s3FuncsManager->forceLogoutOfAllUsers();
|
||||
$s3FuncsManager->duplicatorMigrationInfoSet();
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_NOTICE_TEST:
|
||||
$s3FuncsManager->checkForIndexHtml();
|
||||
$s3FuncsManager->noticeTest();
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_CLEANUP_TMP_FILES:
|
||||
$s3FuncsManager->cleanupTmpFiles();
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_SET_FILE_PERMS:
|
||||
$s3FuncsManager->setFilePermsission();
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_FINAL_REPORT_NOTICES:
|
||||
$s3FuncsManager->finalReportNotices();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
/**
|
||||
* At each iteration save the status in case of exit with timeout
|
||||
*/
|
||||
$this->saveData();
|
||||
}
|
||||
|
||||
protected function getIterator()
|
||||
{
|
||||
return new DUPX_s3_iterator();
|
||||
}
|
||||
|
||||
public function getStoredDataKey()
|
||||
{
|
||||
return $GLOBALS["CHUNK_DATA_FILE_PATH"];
|
||||
}
|
||||
|
||||
/**
|
||||
* stop iteration without save data.
|
||||
* It is already saved every iteration.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function stop($saveData = false)
|
||||
{
|
||||
return parent::stop(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* load data from previous step if exists adn restore _POST and GLOBALS
|
||||
*
|
||||
* @param string $key file name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getStoredData($key)
|
||||
{
|
||||
if (($data = parent::getStoredData($key)) != null) {
|
||||
Log::info("CHUNK LOAD DATA: POSITION " . implode(' / ', $data['position']), 2);
|
||||
return $data['position'];
|
||||
} else {
|
||||
Log::info("CHUNK LOAD DATA: IS NULL ");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* delete stored data if exists
|
||||
*/
|
||||
protected function deleteStoredData($key)
|
||||
{
|
||||
Log::info("CHUNK DELETE STORED DATA FILE:" . Log::v2str($key), 2);
|
||||
return parent::deleteStoredData($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* save data for next step
|
||||
*/
|
||||
protected function saveStoredData($key, $data)
|
||||
{
|
||||
// store s3 func data
|
||||
$s3Funcs = DUPX_S3_Funcs::getInstance();
|
||||
$s3Funcs->report['chunk'] = 1;
|
||||
$s3Funcs->report['chunkPos'] = $data;
|
||||
$s3Funcs->report['pass'] = 0;
|
||||
$s3Funcs->report['progress_perc'] = $this->getProgressPerc();
|
||||
$s3Funcs->saveData();
|
||||
|
||||
// managed output for timeout shutdown
|
||||
LogHandler::setShutdownReturn(LogHandler::SHUTDOWN_TIMEOUT, SnapJson::jsonEncode($s3Funcs->getJsonReport()));
|
||||
|
||||
/**
|
||||
* store position post and globals
|
||||
*/
|
||||
$gData = array(
|
||||
'position' => $data
|
||||
);
|
||||
|
||||
Log::info("CHUNK SAVE DATA: POSITION " . implode(' / ', $data), 2);
|
||||
return parent::saveStoredData($key, $gData);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return float progress in %
|
||||
*/
|
||||
public function getProgressPerc()
|
||||
{
|
||||
$result = 0;
|
||||
$position = $this->it->getPosition();
|
||||
$s3Func = DUPX_S3_Funcs::getInstance();
|
||||
|
||||
switch ($position['l0']) {
|
||||
case DUPX_s3_iterator::STEP_SEARCH_AND_REPLACE_INIT:
|
||||
$result = 5;
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_SEARCH_AND_REPLACE:
|
||||
$lowLimit = 10;
|
||||
$higthLimit = 90;
|
||||
$stepDelta = $higthLimit - $lowLimit;
|
||||
$tables = DUPX_DB_Tables::getInstance()->getReplaceTablesNames();
|
||||
$tableDelta = $stepDelta / (count($tables) + 1);
|
||||
$singePagePerc = $tableDelta / ($s3Func->cTableParams['pages'] + 1);
|
||||
$result = round($lowLimit + ($tableDelta * (int) $position['l1']) + ($singePagePerc * (int) $position['l2']), 2);
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_REMOVE_MAINTENACE:
|
||||
$result = 90;
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_CREATE_ADMIN:
|
||||
$result = 92;
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_CONF_UPDATE:
|
||||
$result = 93;
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_GEN_UPD:
|
||||
$result = 94;
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_GEN_CLEAN:
|
||||
$result = 95;
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_NOTICE_TEST:
|
||||
$result = 96;
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_CLEANUP_TMP_FILES:
|
||||
$result = 97;
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_SET_FILE_PERMS:
|
||||
$result = 98;
|
||||
break;
|
||||
case DUPX_s3_iterator::STEP_FINAL_REPORT_NOTICES:
|
||||
$result = 100;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Cunking manager
|
||||
*
|
||||
* Standard: PSR-2
|
||||
*
|
||||
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
|
||||
*
|
||||
* @package SC\DUPX\Chunk
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Abstract class to split an single ajax requet in multiple requests
|
||||
*/
|
||||
abstract class DUPX_ChunkingManager
|
||||
{
|
||||
/** @var GenericSeekableIterator */
|
||||
protected $it = null;
|
||||
|
||||
/** @var mixed */
|
||||
protected $position = null;
|
||||
|
||||
/** @var integer max iteration before stop. If 0 have no limit */
|
||||
public $maxIteration = 0;
|
||||
|
||||
/** @var integer timeout in milliseconds before stop exectution */
|
||||
public $timeOut = 0;
|
||||
|
||||
/** @var integer sleep in milliseconds every iteration */
|
||||
public $throttling = 0;
|
||||
|
||||
/** @var float */
|
||||
protected $startTime = null;
|
||||
|
||||
/** @var integer */
|
||||
protected $itCount = 0;
|
||||
|
||||
/**
|
||||
* set params
|
||||
*
|
||||
* @param number $maxIteration
|
||||
* @param number $timeOut
|
||||
* @param number $throttling
|
||||
*/
|
||||
public function __construct($maxIteration = 0, $timeOut = 0, $throttling = 0)
|
||||
{
|
||||
|
||||
$this->maxIteration = $maxIteration;
|
||||
$this->timeOut = $timeOut;
|
||||
$this->throttling = $throttling;
|
||||
$this->it = $this->getIterator();
|
||||
|
||||
if (!is_subclass_of($this->it, 'GenericSeekableIterator')) {
|
||||
throw new Exception('Iterator don\'t extend GenericSeekableIterator');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param boolean $rewind
|
||||
*
|
||||
* @return boolean true if execution completed false if stopped
|
||||
*/
|
||||
public function start($rewind = false)
|
||||
{
|
||||
$this->itCount = 0;
|
||||
$microThrottling = $this->throttling * 1000;
|
||||
|
||||
if ($rewind) {
|
||||
/**
|
||||
* delete store data and rewind
|
||||
*/
|
||||
$this->deleteStoredData($this->getStoredDataKey());
|
||||
$this->it->rewind();
|
||||
} elseif (( $last_position = $this->getStoredData($this->getStoredDataKey()) ) !== null) {
|
||||
/**
|
||||
* load last position if exist and delete it
|
||||
*/
|
||||
$this->deleteStoredData($this->getStoredDataKey());
|
||||
$this->it->gSeek($last_position);
|
||||
$this->it->next();
|
||||
}
|
||||
|
||||
$this->startTime();
|
||||
|
||||
/**
|
||||
* Iterate
|
||||
*/
|
||||
for (; $this->it->valid(); $this->it->next()) {
|
||||
$this->itCount++;
|
||||
|
||||
/**
|
||||
* excetute action for current item
|
||||
*/
|
||||
$this->action($this->it->key(), $this->it->current());
|
||||
|
||||
if ($microThrottling) {
|
||||
usleep($microThrottling);
|
||||
}
|
||||
|
||||
if ($this->maxIteration && $this->itCount >= $this->maxIteration || $this->checkTime() == false) {
|
||||
$this->stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* var bool $saveData is fals don't save data. Used in extended classe fot don't save data on stop.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function stop($saveData = true)
|
||||
{
|
||||
if ($saveData) {
|
||||
if (!$this->saveStoredData($this->getStoredDataKey(), $this->it->getPosition())) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
$position = $this->it->getPosition();
|
||||
$this->it->stopIteration();
|
||||
|
||||
return $position;
|
||||
}
|
||||
|
||||
protected function saveData()
|
||||
{
|
||||
if (!$this->saveStoredData($this->getStoredDataKey(), $this->it->getPosition())) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLastPosition()
|
||||
{
|
||||
return $this->it->getPosition();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return number
|
||||
*/
|
||||
public function getIterationsCount()
|
||||
{
|
||||
return $this->itCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function startTime()
|
||||
{
|
||||
$this->startTime = microtime(true);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function checkTime()
|
||||
{
|
||||
if ($this->timeOut) {
|
||||
$delta = $this->getExecutionTime() * 1000;
|
||||
if ($delta > $this->timeOut) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return number
|
||||
*/
|
||||
public function getExecutionTime()
|
||||
{
|
||||
return microtime(true) - $this->startTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stored data key
|
||||
*/
|
||||
abstract public function getStoredDataKey();
|
||||
|
||||
/**
|
||||
* load data from previous step if exists
|
||||
*/
|
||||
abstract protected function getStoredData($key);
|
||||
|
||||
/**
|
||||
* delete stored data if exists
|
||||
*/
|
||||
abstract protected function deleteStoredData($key);
|
||||
|
||||
/**
|
||||
* save data for next step
|
||||
*/
|
||||
abstract protected function saveStoredData($key, $data);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $current
|
||||
*/
|
||||
abstract protected function action($key, $current);
|
||||
|
||||
/**
|
||||
* @return GenericSeekableIterator
|
||||
*/
|
||||
abstract protected function getIterator();
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
abstract public function getProgressPerc();
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Cunking manager with stored data in json file.
|
||||
*
|
||||
* Standard: PSR-2
|
||||
*
|
||||
* @link http://www.php-fig.org/psr/psr-2 Full Documentation
|
||||
*
|
||||
* @package SC\DUPX\Chunk
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
||||
|
||||
use Duplicator\Libs\Snap\SnapJson;
|
||||
|
||||
require_once(DUPX_INIT . '/classes/chunk/class.chunkingmanager.php');
|
||||
|
||||
/**
|
||||
* Store position on json file
|
||||
*/
|
||||
abstract class DUPX_ChunkingManager_file extends DUPX_ChunkingManager
|
||||
{
|
||||
/**
|
||||
* load data from previous step if exists
|
||||
*
|
||||
* @param string $key file name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getStoredData($key)
|
||||
{
|
||||
if (file_exists($key)) {
|
||||
$data = file_get_contents($key);
|
||||
return json_decode($data, true);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* delete stored data if exists
|
||||
*/
|
||||
protected function deleteStoredData($key)
|
||||
{
|
||||
if (file_exists($key)) {
|
||||
unlink($key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $key file path
|
||||
* @param mixed $data to save in file path
|
||||
*
|
||||
* @return boolean|int This function returns the number of bytes that were written to the file, or FALSE on failure.
|
||||
*/
|
||||
protected function saveStoredData($key, $data)
|
||||
{
|
||||
if (($json = SnapJson::jsonEncode($data)) === false) {
|
||||
throw new Exception('Json encode chunk data error');
|
||||
}
|
||||
|
||||
return file_put_contents($key, $json);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user