![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/app/code/Soon/DataSync/Model/ |
<?php /** * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @author Hervé Guétin <[email protected]> <@herveguetin> * @copyright Copyright (c) 2017 Agence Soon (http://www.agence-soon.fr) */ namespace Soon\DataSync\Model; use Magento\Framework\App\Filesystem\DirectoryList; use Soon\DataSync\Model\Data\DataInterface; use Soon\DataSync\Model\Data\Type\DataTypeInterface; use Soon\DataSync\Model\FileFactory; use Soon\DataSync\Model\Job\JobInterface; use Soon\DataSync\Model\Transfer\TransferInterface; use Soon\DataSync\Model\Transfer\Type\TransferTypeInterface; class Sync implements SyncInterface { const DIRECTION_IMPORT = 'import'; const DIRECTION_EXPORT = 'export'; /** * @var DataInterface */ private $data; /** * @var DataTypeInterface */ private $dataType; /** * @var array */ private $dataTypeConfig; /** * @var TransferInterface */ private $transfer; /** * @var TransferTypeInterface */ private $transferType; /** * @var array */ private $transferTypeConfig; /** * @var string */ private $direction = null; /** * @var JobInterface */ private $job; /** * @var string|bool */ private $archiveFilePath; /** * @var string */ private $archiveDirPath; /** * @var DirectoryList */ private $directoryList; /** * @var \Closure */ private $syncClosure; /** * @var FileFactory */ private $fileFactory; /** * @var bool */ private $clean; /** * @var string */ private $glob; public function __construct( DataInterface $data, TransferInterface $transfer, DirectoryList $directoryList, FileFactory $fileFactory ) { $this->data = $data; $this->transfer = $transfer; $this->directoryList = $directoryList; $this->fileFactory = $fileFactory; } /** * @param string $path * @return SyncInterface */ public function glob(string $path): SyncInterface { $this->direction(self::DIRECTION_IMPORT); $this->glob = $path; return $this; } private function direction(string $direction) { if (is_null($this->direction)) { $this->direction = $direction; } if ($direction !== $this->direction) { throw new \Exception(sprintf('This job is already being used as an %s', $this->direction)); } } /** * @param string $transfer * @param array $config * @return SyncInterface */ public function fromOnce(string $transfer, array $config = []): SyncInterface { $this->from($transfer, $config); $this->clean = true; return $this; } /** * @param string $transfer * @param array $config * @return SyncInterface */ public function from(string $transfer, array $config = []): SyncInterface { $this->clean = false; $this->direction(self::DIRECTION_IMPORT); $this->prepareTransferType($transfer, $config); return $this; } /** * @param string $transfer * @param array $config */ private function prepareTransferType(string $transfer, array $config) { $this->transferTypeConfig = $config; $this->transferType = $this->transfer->type($transfer); $this->transferType->configure(array_merge($config, ['job' => $this->job])); } /** * @param string $transfer * @param array $config * @return SyncInterface */ public function to(string $transfer, array $config = []): SyncInterface { $this->direction(self::DIRECTION_EXPORT); $this->prepareTransferType($transfer, $config); return $this; } /** * @return SyncInterface */ public function go(): SyncInterface { $this->defaults(); $this->assertCanSync(); if ($this->glob) { $this->goGlob(); $this->reset(); return $this; } $this->process(); $this->clean(); $this->reset(); return $this; } /** * Let's set some defaults for an easier an error-less sync */ private function defaults() { if (is_null($this->dataType)) { $this->dataOfType('csv'); } if (is_null($this->archiveFilePath)) { $this->archive(); } } /** * @param string $format * @param array $config * @return SyncInterface */ public function dataOfType(string $format, array $config = []): SyncInterface { $this->dataTypeConfig = $config; $this->dataType = $this->data->type($format); $this->dataType->configure(array_merge($config, ['job' => $this->job])); return $this; } /** * @param null|bool $path * @return SyncInterface */ public function archive($path = null): SyncInterface { if ($path === false) { $this->archiveFilePath = false; return $this; } $archiveFilePath = (is_null($path)) ? $this->defaultArchiveFilePath() : $path; $this->archiveFilePath = $archiveFilePath; $pathArr = explode('/', $archiveFilePath); array_pop($pathArr); $this->archiveDirPath = implode('/', $pathArr); return $this; } /** * @return string */ private function defaultArchiveFilePath() { $varDir = $this->directoryList->getPath(DirectoryList::VAR_DIR) . '/soon_datasync/_archive'; $dateTime = (new \DateTime())->format('Y-m-d_H:i:s'); return sprintf('%s/%s/%s_%s', $varDir, $this->direction, $this->job->getCode(), $dateTime); } private function assertCanSync() { if (is_null($this->dataType)) { throw new \Exception('Please specifiy a type of data using dataOfType()'); } if (is_null($this->transferType) || is_null($this->direction)) { throw new \Exception('Please specifiy a type of transfer using from() for import or to() for export'); } if (is_null($this->syncClosure)) { throw new \Exception('Please specify a Closure that prepares the data (for export) or loop on data (import). Pass your Closure with treatWith()'); } } /** * @return Sync */ private function goGlob() { array_map(function ($file) { $sync = new self($this->data, $this->transfer, $this->directoryList, $this->fileFactory); // Job $sync->job($this->job); // Data $sync->dataOfType($this->dataType->code(), $this->dataTypeConfig); // Transfer $transferConfig = $this->transferTypeConfig; $transferConfig['filepath'] = $file; $transferMethod = ($this->clean) ? 'fromOnce' : 'from'; $sync->{$transferMethod}($this->transferType->code(), $transferConfig); // Treatment $sync->treatWith($this->syncClosure); // Archive $pathArr = explode('/', $file); $fileArr = explode('.', end($pathArr)); $sync->archive(sprintf('%s_%s', $this->archiveFilePath, reset($fileArr))); // Go! $sync->go(); }, $this->transferType->glob($this->glob)); return $this; } public function job(JobInterface $job) { $this->job = $job; } /** * @param \Closure $closure * @return SyncInterface */ public function treatWith(\Closure $closure): SyncInterface { $this->syncClosure = $closure; return $this; } private function process() { if ($this->direction === self::DIRECTION_IMPORT) { $this->import(); } if ($this->direction === self::DIRECTION_EXPORT) { $this->export(); } } private function import() { $rawData = $this->transferType->pull(); $data = $this->dataType->parse($rawData); ($this->syncClosure)($data); $this->saveArchive($rawData); } private function saveArchive(string $data) { if ($this->archiveFilePath) { /** @var File $io */ $io = $this->fileFactory->create(['file' => $this->archiveFilePath]); $io->write($data); } } private function export() { $data = ($this->syncClosure)(); $push = $this->dataType->convert($data); $this->transferType->push($push); $this->saveArchive($push); } private function clean() { if ($this->clean) { $this->transferType->clean(); } } public function reset() { $this->glob = null; $this->direction = null; $this->dataType = null; $this->transferType = null; $this->archiveFilePath = null; $this->archiveDirPath = null; $this->syncClosure = null; } /** * @param string $info * @return mixed */ public function which(string $info) { return $this->{$info}; } }