Created
November 7, 2021 18:14
-
-
Save alroniks/3a624e4310bf76c648cbc91d519f0ff1 to your computer and use it in GitHub Desktop.
shopmanager.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
Скрипт, который позволяет принимать запросы от shopmanager и обновлять информацию на сайте на базе MODX и miniSgop2, | |
при включенной интеграции. | |
Скрипт не закончен, потому использовать на свой страх и риск. | |
*/ | |
declare(strict_types = 1); | |
require __DIR__ . '/config.core.php'; | |
require MODX_CORE_PATH . 'model/modx/modx.class.php'; | |
$modx = new modX(); | |
$modx->initialize('mgr'); | |
$modx->getService('error','error.modError', '', ''); | |
$modx->setLogTarget(['target' => 'FILE', 'options' => ['filename' => 'import.log']]); | |
$modx->setLogLevel(xPDO::LOG_LEVEL_DEBUG); | |
/** | |
* Usage: curl -d '{"products":[{"id":"12345","price":"12.63","origPrice":"10.03","inStock":1,"origStock":34,"delivery":{}}], "staledProductsIds":["501-233","502-230"]}' -H "SMKey: somekey" -X POST https://sitename.com/site-import.php | |
*/ | |
final class SiteImporter { | |
private const KEY = 'some key'; | |
private const HEADER_KEY = 'HTTP_SMKEY'; | |
private const HEADER_SYNC_TYPE = 'HTTP_SMSyncType'; | |
private const STATUS_OK = 0; | |
private const STATUS_UNAUTORIZED = 100; | |
private const STATUS_ERROR = 101; | |
private const SYNC_TYPE_FULL = 'full'; | |
private const SYNC_TYPE_PARTIAL = 'partial'; | |
private const STATS_UPDATED = 'updated'; | |
private const STATS_SKIPPED = 'skipped'; | |
private const STATS_ERRORED = 'errored'; | |
private modX $modx; | |
private string $syncType = self::SYNC_TYPE_PARTIAL; | |
private array $stats = [ | |
self::STATS_UPDATED => 0, | |
self::STATS_SKIPPED => 0, | |
self::STATS_ERRORED => 0, | |
]; | |
/** | |
* @throws \JsonException | |
*/ | |
public function __construct(modX $modx) | |
{ | |
if ($_SERVER[self::HEADER_KEY] !== self::KEY) { | |
self::result(self::STATUS_UNAUTORIZED); | |
} | |
if (isset($_SERVER[self::HEADER_SYNC_TYPE])) { | |
$this->syncType = $_SERVER[self::HEADER_SYNC_TYPE]; | |
} | |
$this->modx = $modx; | |
$this->modx->log(xPDO::LOG_LEVEL_DEBUG, sprintf('Incoming authorization key: %s', $_SERVER[self::HEADER_KEY])); | |
$this->modx->log(xPDO::LOG_LEVEL_DEBUG, sprintf('Incoming sync type: %s', $_SERVER[self::HEADER_SYNC_TYPE])); | |
} | |
/** | |
* @throws \JsonException | |
*/ | |
public function __invoke(): string | |
{ | |
$data = json_decode(file_get_contents('php://input'), true, 512, JSON_THROW_ON_ERROR); | |
$this->modx->log(xPDO::LOG_LEVEL_DEBUG, sprintf('Incoming request details: %s', self::arrayOneLine($data))); | |
if (isset($data['staledProductsIds']) && is_array($data['staledProductsIds']) && count($data['staledProductsIds'])) { | |
$annulled = 0; | |
foreach ($data['staledProductsIds'] as $id) { | |
if ($this->toNullProduct($id)) { | |
$annulled++; | |
} | |
} | |
$this->modx->log(xPDO::LOG_LEVEL_INFO, sprintf('%s products were annulled', $annulled)); | |
$this->modx->log(xPDO::LOG_LEVEL_DEBUG, sprintf('where touched products with articles: %s', implode(',', $data['staledProductsIds']))); | |
} | |
switch ($this->syncType) { | |
case self::SYNC_TYPE_PARTIAL: | |
$this->onceProcessing($data['products']); | |
break; | |
case self::SYNC_TYPE_FULL: | |
$this->bulkProcessing($data['products']); | |
break; | |
} | |
self::result(self::STATUS_OK, $this->stats); | |
} | |
private function bulkProcessing(array $products): void | |
{ | |
// return; | |
// $touchedProducts = $this->modx->getIterator( | |
// msProductData::class, | |
// ['article:IN' => array_column($products, 'id')] | |
// ); | |
// | |
// // | |
// | |
// $prices = []; | |
// foreach ($touchedProducts as $product) { | |
// $prices[$product->get('article')] = array_filter( | |
// $product->toArray(), | |
// static fn($key) => in_array($key, ['id', 'article', 'price', 'old_price', 'remain']), | |
// ARRAY_FILTER_USE_KEY | |
// ); | |
// } | |
} | |
/** | |
* @param array[] $products | |
*/ | |
private function onceProcessing(array $products): void | |
{ | |
foreach ($products as $productInfo) { | |
$this->modx->log(xPDO::LOG_LEVEL_INFO, sprintf('Importing product with id "%s"', $productInfo['id'])); | |
$this->modx->log(xPDO::LOG_LEVEL_DEBUG, self::arrayOneLine($productInfo)); | |
try { | |
/** @var msProductData $productData */ | |
$productData = $this->modx->getObject( | |
msProductData::class, | |
['article' => $productInfo['id']] | |
); | |
/** @var msProduct $product */ | |
$product = $productData->getOne('Product'); | |
if ($this->updateProduct($product, $productData['price'], $productData['origPrice'], $productData['origStock'])) { | |
$this->modx->log(xPDO::LOG_LEVEL_INFO, sprintf('Updated product with id %d', $product->get('id'))); | |
$this->modx->log(xPDO::LOG_LEVEL_DEBUG, sprintf('Updated product with id %d', $product->get('id'))); | |
$this->stats[self::STATS_UPDATED]++; | |
} | |
} catch (Exception $e) { | |
$this->modx->log(xPDO::LOG_LEVEL_ERROR, $e->getMessage()); | |
$this->stats[self::STATS_ERRORED]++; | |
} | |
} | |
} | |
private function toNullProduct(string $article): bool | |
{ | |
$product = $this->modx->getObject(msProductData::class, ['article' => $article]); | |
if (!$product) { | |
return false; | |
} | |
return $this->updateProduct($product->getOne('Product'), '0.00','0.00', 0); | |
} | |
/** | |
* @throws \JsonException | |
*/ | |
public static function result(int $status = self::STATUS_ERROR, array $stats = []): void | |
{ | |
$result = ['status' => $status]; | |
if (count($stats)) { | |
$result = array_merge($result, $stats); | |
} | |
header('SMRESULT: ' . json_encode($result, JSON_THROW_ON_ERROR)); exit; | |
} | |
private function updateProduct(msProduct $product, string $retailPrice, string $tradePrice, int $balance): bool | |
{ | |
$product->set('price', $retailPrice); | |
$product->set('old_price', $tradePrice); | |
return $product->setTVValue('remain', $balance); | |
} | |
private static function arrayOneLine(array $array): string | |
{ | |
return preg_replace('/\s/', '', str_replace(PHP_EOL, '', var_export($array, true))); | |
} | |
} | |
try { | |
echo (new SiteImporter($modx))(); | |
exit(); | |
} catch (JsonException $e) { | |
SiteImporter::result(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment