From 0f258bb9398f8b734a6c84427f5b5e4a9d517b7d Mon Sep 17 00:00:00 2001 From: "John.R" Date: Fri, 26 Jul 2024 17:18:05 +0200 Subject: [PATCH] refactor: synchronization service and connected services --- src/Config/Config.php | 9 + src/Controller/AbstractApiController.php | 4 +- .../ShopContentServiceInterface.php | 10 + src/Service/SynchronizationService.php | 229 +++++++++--------- 4 files changed, 136 insertions(+), 116 deletions(-) create mode 100644 src/Interfaces/ShopContentServiceInterface.php diff --git a/src/Config/Config.php b/src/Config/Config.php index bcf698ef..3116edc9 100644 --- a/src/Config/Config.php +++ b/src/Config/Config.php @@ -62,6 +62,15 @@ class Config const COLLECTION_WISHLISTS = 'wishlists'; const COLLECTION_WISHLIST_PRODUCTS = 'wishlist_products'; + const MYSQL_DATE_FORMAT = 'Y-m-d H:i:s'; + + const RANDOM_SYNC_CHECK_MAX = 20; + const INCREMENTAL_SYNC_MAX_ITEMS_PER_SHOP_CONTENT = 100000; + + const INCREMENTAL_TYPE_ADD = 'incremental_type_add'; + const INCREMENTAL_TYPE_UPDATE = 'incremental_type_update'; + const INCREMENTAL_TYPE_DELETE = 'incremental_type_delete'; + /** * @param mixed $message * diff --git a/src/Controller/AbstractApiController.php b/src/Controller/AbstractApiController.php index e5b34bf8..a708d3c3 100644 --- a/src/Controller/AbstractApiController.php +++ b/src/Controller/AbstractApiController.php @@ -17,8 +17,6 @@ use PrestaShop\Module\PsEventbus\Service\PsAccountsAdapterService; use PrestaShop\Module\PsEventbus\Service\SynchronizationService; -const MYSQL_DATE_FORMAT = 'Y-m-d H:i:s'; - abstract class AbstractApiController extends \ModuleFrontController { /** @@ -187,7 +185,7 @@ protected function handleDataSync(PaginatedApiDataProviderInterface $dataProvide $configurationRepository = $this->module->getService(\PrestaShop\Module\PsEventbus\Repository\ConfigurationRepository::class); $timezone = (string) $configurationRepository->get('PS_TIMEZONE'); - $dateNow = (new \DateTime('now', new \DateTimeZone($timezone)))->format(MYSQL_DATE_FORMAT); + $dateNow = (new \DateTime('now', new \DateTimeZone($timezone)))->format(Config::MYSQL_DATE_FORMAT); $offset = 0; $incrementalSync = false; $response = []; diff --git a/src/Interfaces/ShopContentServiceInterface.php b/src/Interfaces/ShopContentServiceInterface.php new file mode 100644 index 00000000..b52c7760 --- /dev/null +++ b/src/Interfaces/ShopContentServiceInterface.php @@ -0,0 +1,10 @@ +module = $module; $this->eventbusSyncRepository = $eventbusSyncRepository; $this->incrementalSyncRepository = $incrementalSyncRepository; $this->liveSyncRepository = $liveSyncRepository; $this->deletedObjectsRepository = $deletedObjectsRepository; $this->languageRepository = $languageRepository; + $this->proxyService = $proxyService; $this->payloadDecorator = $payloadDecorator; } /** - * @param PaginatedApiDataProviderInterface $dataProvider - * @param string $type + * @param string $shopContent * @param string $jobId * @param string $langIso * @param int $offset * @param int $limit + * @param int $startTime * @param string $dateNow - * @param int $scriptStartTime - * @param bool $isFull + * @param bool $debug * - * @return array + * @return array * * @@throws \PrestaShopDatabaseException|EnvVarException|ApiException */ - public function handleFullSync( - PaginatedApiDataProviderInterface $dataProvider, - $type, - $jobId, - $langIso, - $offset, - $limit, - $dateNow, - $scriptStartTime, - $isFull + public function sendFullSync( + string $shopContent, + string $jobId, + string $langIso, + int $offset, + int $limit, + int $startTime, + string $dateNow, + bool $debug ) { $response = []; - $data = $dataProvider->getFormattedData($offset, $limit, $langIso); + $serviceName = str_replace('-', '', ucwords($shopContent, "-")); + $serviceId = 'PrestaShop\Module\PsEventbusV4\Services\\' . $serviceName . 'Service'; // faire un mapping entre le service et le nom du shopcontent + + /** @var Ps_eventbus */ + $module = \Module::getInstanceByName('ps_eventbus'); + + if (!$module->hasService($serviceId)) { + throw new ServiceNotFoundException('Service ' . $serviceName . 'doesn\'t exist !', $serviceId); + } + + /** @var ShopContentServiceInterface $shopContentApiService */ + $shopContentApiService = $this->module->getService($serviceId); + + /** @var ConfigurationRepository $configurationRepository */ + $configurationRepository = $this->module->getService('PrestaShop\Module\PsEventbusV4\Repository\ConfigurationRepository'); + + $timezone = (string) $configurationRepository->get('PS_TIMEZONE'); + $dateNow = (new \DateTime('now', new \DateTimeZone($timezone)))->format(Config::MYSQL_DATE_FORMAT); + + $data = $shopContentApiService->getContentsForFull($offset, $limit, $langIso, $debug); $this->payloadDecorator->convertDateFormat($data); if (!empty($data)) { - /** @var ProxyService */ - $proxyService = $this->module->getService('PrestaShop\Module\PsEventbus\Service\ProxyService'); - - $response = $proxyService->upload($jobId, $data, $scriptStartTime, $isFull); + $response = $this->proxyService->upload($jobId, $data, $startTime, true); if ($response['httpCode'] == 201) { $offset += $limit; } } - $remainingObjects = (int) $dataProvider->getRemainingObjectsCount($offset, $langIso); + $remainingObjects = (int) $shopContentApiService->countFullSyncContentLeft($offset, $langIso); if ($remainingObjects <= 0) { $remainingObjects = 0; $offset = 0; } - $this->eventbusSyncRepository->updateTypeSync($type, $offset, $dateNow, $remainingObjects === 0, $langIso); + $this->eventbusSyncRepository->updateTypeSync($shopContent, $offset, $dateNow, $remainingObjects === 0, $langIso); return $this->returnSyncResponse($data, $response, $remainingObjects); } /** - * @param PaginatedApiDataProviderInterface $dataProvider * @param string $type * @param string $jobId - * @param int $limit * @param string $langIso - * @param int $scriptStartTime - * @param bool $isFull + * @param int $limit + * @param int $startTime + * @param bool $debug * - * @return array + * @return array * * @@throws \PrestaShopDatabaseException|EnvVarException */ - public function handleIncrementalSync( - PaginatedApiDataProviderInterface $dataProvider, - $type, - $jobId, - $limit, - $langIso, - $scriptStartTime, - $isFull + public function sendIncrementalSync( + string $shopContent, + string $jobId, + string $langIso, + int $limit, + int $startTime, + bool $debug ) { $response = []; - $objectIds = $this->incrementalSyncRepository->getIncrementalSyncObjectIds($type, $langIso, $limit); + $serviceName = str_replace('-', '', ucwords($shopContent, "-")); + + /** @var ShopContentServiceInterface $shopContentApiService */ + $shopContentApiService = $this->module->getService('PrestaShop\\Module\\PsEventbus\\Services\\' . $serviceName . 'Service'); + + $contentIds = $this->incrementalSyncRepository->getIncrementalSyncObjectIds($shopContent, $langIso, $limit); - if (empty($objectIds)) { + if (empty($contentIds)) { return [ 'total_objects' => 0, 'has_remaining_objects' => false, @@ -164,24 +179,21 @@ public function handleIncrementalSync( ]; } - $data = $dataProvider->getFormattedDataIncremental($limit, $langIso, $objectIds); + $data = $shopContentApiService->getContentsForIncremental($limit, $contentIds, $langIso, $debug); $this->payloadDecorator->convertDateFormat($data); if (!empty($data)) { - /** @var ProxyService */ - $proxyService = $this->module->getService('PrestaShop\Module\PsEventbus\Service\ProxyService'); - - $response = $proxyService->upload($jobId, $data, $scriptStartTime, $isFull); + $response = $this->proxyService->upload($jobId, $data, $startTime, false); if ($response['httpCode'] == 201) { - $this->incrementalSyncRepository->removeIncrementalSyncObjects($type, $objectIds, $langIso); + $this->incrementalSyncRepository->removeIncrementalSyncObjects($shopContent, $contentIds, $langIso); } } else { - $this->incrementalSyncRepository->removeIncrementalSyncObjects($type, $objectIds, $langIso); + $this->incrementalSyncRepository->removeIncrementalSyncObjects($shopContent, $contentIds, $langIso); } - $remainingObjects = $this->incrementalSyncRepository->getRemainingIncrementalObjects($type, $langIso); + $remainingObjects = $this->incrementalSyncRepository->getRemainingIncrementalObjects($shopContent, $langIso); return $this->returnSyncResponse($data, $response, $remainingObjects); } @@ -203,17 +215,17 @@ public function sendLiveSync($shopContent, $shopContentId, $action) } /** - * @param int $objectId - * @param string $type + * @param array> $contentTypesWithIds + * @param string actionType * @param string $createdAt * @param int $shopId * @param bool $hasMultiLang * * @return void */ - public function insertIncrementalSyncObject($objectId, $type, $createdAt, $shopId, $hasMultiLang = null) + public function insertContentIntoIncremental($contentTypesWithIds, $actionType, $createdAt, $shopId, $hasMultiLang = null) { - if ((int) $objectId === 0) { + if (count($contentTypesWithIds) == 0) { return; } @@ -222,80 +234,71 @@ public function insertIncrementalSyncObject($objectId, $type, $createdAt, $shopI * When random number == 10, we count number of entry exist in database for this specific shop content * If count > 100 000, we removed all entry corresponding to this shop content, and we enable full sync for this */ - if (mt_rand() % $this::RANDOM_SYNC_CHECK_MAX == 0) { - $count = $this->incrementalSyncRepository->getIncrementalSyncObjectCountByType($type); - if ($count > $this::INCREMENTAL_SYNC_MAX_ITEMS_PER_SHOP_CONTENT) { - $hasDeleted = $this->incrementalSyncRepository->removeIncrementaSyncObjectByType($type); - - if ($hasDeleted) { - $this->eventbusSyncRepository->updateTypeSync( - $type, - 0, - $createdAt, - false, - $this->languageRepository->getDefaultLanguageIsoCode() - ); + if (mt_rand() % Config::RANDOM_SYNC_CHECK_MAX == 0) { + foreach($contentTypesWithIds as $contentType => $contentIds) { + $count = $this->incrementalSyncRepository->getIncrementalSyncObjectCountByType($contentType); + + if ($count > Config::INCREMENTAL_SYNC_MAX_ITEMS_PER_SHOP_CONTENT) { + $hasDeleted = $this->incrementalSyncRepository->removeIncrementaSyncObjectByType($contentType); + + if ($hasDeleted) { + $this->eventbusSyncRepository->updateTypeSync( + $contentType, + 0, + $createdAt, + false, + $this->languageRepository->getDefaultLanguageIsoCode() + ); + } } - } - return; + return; + } } - $objectsData = []; + $contentToInsert = []; if ($hasMultiLang) { $allIsoCodes = $this->languageRepository->getLanguagesIsoCodes(); foreach ($allIsoCodes as $langIso) { - if ($this->isFullSyncDone($type, $langIso)) { - array_push($objectsData, + foreach($contentTypesWithIds as $contentType => $contentIds) { + if ($this->isFullSyncDone($contentType, $langIso)) { + array_push($contentToInsert, + [ + 'type' => $contentType, + 'id_object' => $contentIds, + 'id_shop' => $shopId, + 'lang_iso' => $langIso, + 'action' => $actionType, + 'created_at' => $createdAt, + ] + ); + } + } + } + } else { + $defaultIsoCode = $this->languageRepository->getDefaultLanguageIsoCode(); + + foreach($contentTypesWithIds as $contentType => $contentIds) { + if ($this->isFullSyncDone($contentType, $defaultIsoCode)) { + array_push($contentToInsert, [ - 'type' => $type, - 'id_object' => $objectId, + 'type' => $contentType, + 'id_object' => $contentIds, 'id_shop' => $shopId, - 'lang_iso' => $langIso, + 'lang_iso' => $defaultIsoCode, + 'action' => $actionType, 'created_at' => $createdAt, ] ); } } - } else { - $defaultIsoCode = $this->languageRepository->getDefaultLanguageIsoCode(); - - if ($this->isFullSyncDone($type, $defaultIsoCode)) { - array_push($objectsData, - [ - 'type' => $type, - 'id_object' => $objectId, - 'id_shop' => $shopId, - 'lang_iso' => $defaultIsoCode, - 'created_at' => $createdAt, - ] - ); - } - } - - if (empty($objectsData) == false) { - $this->incrementalSyncRepository->insertIncrementalObject($objectsData); } - } - /** - * @param int $objectId - * @param string $type - * @param string $date - * @param int $shopId - * - * @return void - */ - public function insertDeletedObject($objectId, $type, $date, $shopId) - { - if ((int) $objectId === 0) { - return; + if (empty($contentToInsert) == false) { + $this->incrementalSyncRepository->insertIncrementalObject($contentToInsert); } - - $this->deletedObjectsRepository->insertDeletedObject($objectId, $type, $date, $shopId); - $this->incrementalSyncRepository->removeIncrementalSyncObject($type, $objectId); } /**