diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 35e1033..2f3bff7 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -1,7 +1,7 @@ name: Run PHP Static Analysis on: pull_request - + jobs: code-standards: runs-on: ubuntu-latest @@ -11,7 +11,7 @@ jobs: with: fetch-depth: 0 - name: Code Standards Test - uses: docker://aligent/code-standards-pipe-php:7.4 + uses: docker://aligent/code-standards-pipe-php:8.1 env: STANDARDS: "Magento2" SKIP_DEPENDENCIES: "true" diff --git a/Api/Data/PrerenderRecachingManagementRequestInterface.php b/Api/Data/PrerenderRecachingManagementRequestInterface.php new file mode 100644 index 0000000..a649114 --- /dev/null +++ b/Api/Data/PrerenderRecachingManagementRequestInterface.php @@ -0,0 +1,61 @@ +scopeConfig = $scopeConfig; + public function __construct( + private readonly ScopeConfigInterface $scopeConfig + ) { } /** diff --git a/Model/Api/Data/PrerenderRecachingManagementRequest.php b/Model/Api/Data/PrerenderRecachingManagementRequest.php new file mode 100644 index 0000000..527d125 --- /dev/null +++ b/Model/Api/Data/PrerenderRecachingManagementRequest.php @@ -0,0 +1,63 @@ +getData(self::BATCH_URLS); + } + + /** + * @inheritDoc + */ + public function setBatchUrls(string $batchUrls): void + { + $this->setData(self::BATCH_URLS, $batchUrls); + } + + /** + * @inheritDoc + */ + public function getStoreId(): int + { + return $this->getData(self::STORE_ID); + } + + /** + * @inheritDoc + */ + public function setStoreId(int $storeId): void + { + $this->setData(self::STORE_ID, $storeId); + } + + /** + * @inheritDoc + */ + public function getIndexerId(): string + { + return $this->getData(self::INDEXER_ID); + } + + /** + * @inheritDoc + */ + public function setIndexerId(string $indexerId): void + { + $this->setData(self::INDEXER_ID, $indexerId); + } +} diff --git a/Model/Api/PrerenderClient.php b/Model/Api/PrerenderClient.php index fc96674..965bfc8 100644 --- a/Model/Api/PrerenderClient.php +++ b/Model/Api/PrerenderClient.php @@ -18,15 +18,6 @@ class PrerenderClient implements PrerenderClientInterface private const MAX_URLS = 1000; - /** @var Config */ - private Config $prerenderConfigHelper; - /** @var ClientInterface */ - private ClientInterface $client; - /** @var SerializerInterface */ - private SerializerInterface $jsonSerializer; - /** @var LoggerInterface */ - private LoggerInterface $logger; - /** * * @param Config $prerenderConfigHelper @@ -35,15 +26,11 @@ class PrerenderClient implements PrerenderClientInterface * @param LoggerInterface $logger */ public function __construct( - Config $prerenderConfigHelper, - ClientInterface $client, - SerializerInterface $jsonSerializer, - LoggerInterface $logger + private readonly Config $prerenderConfigHelper, + private readonly ClientInterface $client, + private readonly SerializerInterface $jsonSerializer, + private readonly LoggerInterface $logger ) { - $this->prerenderConfigHelper = $prerenderConfigHelper; - $this->jsonSerializer = $jsonSerializer; - $this->logger = $logger; - $this->client = $client; $this->client->addHeader('content-type', 'application/json'); } diff --git a/Model/Api/PrerenderRecachingManagement.php b/Model/Api/PrerenderRecachingManagement.php new file mode 100644 index 0000000..8a0e6c9 --- /dev/null +++ b/Model/Api/PrerenderRecachingManagement.php @@ -0,0 +1,50 @@ +prerenderClient->recacheUrls( + $this->json->unserialize($prerenderRecachingManagementRequest->getBatchUrls()), + $prerenderRecachingManagementRequest->getStoreId() + ); + $message = 'INFO: Recaching Urls successfully synced for ' . + $prerenderRecachingManagementRequest->getIndexerId(); + } catch (Exception $exception) { + $message = 'ERROR: There was an error syncing the Recaching Urls for ' . + $prerenderRecachingManagementRequest->getIndexerId() . $exception->getMessage(); + } + return $message; + } +} diff --git a/Model/Indexer/Category/CategoryIndexer.php b/Model/Indexer/Category/CategoryIndexer.php index ed04b08..59348b9 100644 --- a/Model/Indexer/Category/CategoryIndexer.php +++ b/Model/Indexer/Category/CategoryIndexer.php @@ -10,6 +10,10 @@ use Aligent\Prerender\Api\PrerenderClientInterface; use Aligent\Prerender\Helper\Config; use Aligent\Prerender\Model\Url\GetUrlsForCategories; +use Aligent\Prerender\Api\Data\PrerenderRecachingManagementRequestInterfaceFactory + as PrerenderRecachingManagementRequest; +use Magento\AsynchronousOperations\Model\MassSchedule; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\App\DeploymentConfig; use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Exception\LocalizedException; @@ -25,42 +29,31 @@ class CategoryIndexer implements IndexerActionInterface, MviewActionInterface, D private const INDEXER_ID = 'prerender_category'; private const DEPLOYMENT_CONFIG_INDEXER_BATCHES = 'indexer/batch_size/'; - /** @var DimensionProviderInterface */ - private DimensionProviderInterface $dimensionProvider; - /** @var GetUrlsForCategories */ - private GetUrlsForCategories $getUrlsForCategories; - /** @var PrerenderClientInterface */ - private PrerenderClientInterface $prerenderClient; - /** @var DeploymentConfig */ - private DeploymentConfig $eploymentConfig; - /** @var Config */ - private Config $prerenderConfigHelper; /** @var int|null */ private ?int $batchSize; /** - * * @param DimensionProviderInterface $dimensionProvider * @param GetUrlsForCategories $getUrlsForCategories * @param PrerenderClientInterface $prerenderClient * @param DeploymentConfig $deploymentConfig * @param Config $prerenderConfigHelper + * @param PrerenderRecachingManagementRequest $prerenderRecachingManagementRequest + * @param MassSchedule $massSchedule * @param int|null $batchSize */ public function __construct( - DimensionProviderInterface $dimensionProvider, - GetUrlsForCategories $getUrlsForCategories, - PrerenderClientInterface $prerenderClient, - DeploymentConfig $deploymentConfig, - Config $prerenderConfigHelper, + private readonly DimensionProviderInterface $dimensionProvider, + private readonly GetUrlsForCategories $getUrlsForCategories, + private readonly PrerenderClientInterface $prerenderClient, + private readonly DeploymentConfig $deploymentConfig, + private readonly Config $prerenderConfigHelper, + private readonly PrerenderRecachingManagementRequest $prerenderRecachingManagementRequest, + private readonly MassSchedule $massSchedule, + private readonly Json $json, ?int $batchSize = 1000 ) { - $this->dimensionProvider = $dimensionProvider; - $this->getUrlsForCategories = $getUrlsForCategories; - $this->prerenderClient = $prerenderClient; - $this->deploymentConfig = $deploymentConfig; $this->batchSize = $batchSize; - $this->prerenderConfigHelper = $prerenderConfigHelper; } /** @@ -129,7 +122,9 @@ public function execute($ids): void public function executeByDimensions(array $dimensions, \Traversable $entityIds): void { if (count($dimensions) > 1 || !isset($dimensions[StoreDimensionProvider::DIMENSION_NAME])) { - throw new \InvalidArgumentException('Indexer "' . self::INDEXER_ID . '" supports only Store dimension'); + throw new \InvalidArgumentException( + 'Indexer "' . self::INDEXER_ID . '" supports only Store dimension' + ); } $storeId = (int)$dimensions[StoreDimensionProvider::DIMENSION_NAME]->getValue(); @@ -147,7 +142,11 @@ public function executeByDimensions(array $dimensions, \Traversable $entityIds): $urlBatches = array_chunk($urls, $this->batchSize); foreach ($urlBatches as $batchUrls) { - $this->prerenderClient->recacheUrls($batchUrls, $storeId); + $request = $this->prerenderRecachingManagementRequest->create(); + $request->setBatchUrls($this->json->serialize($batchUrls)); + $request->setStoreId((int) $storeId); + $request->setIndexerId(self::INDEXER_ID); + $this->massSchedule->publishMass('asynchronous.prerender.recaching', [[$request]]); } } } diff --git a/Model/Indexer/Category/ProductIndexer.php b/Model/Indexer/Category/ProductIndexer.php index e5d1a86..8010a4b 100644 --- a/Model/Indexer/Category/ProductIndexer.php +++ b/Model/Indexer/Category/ProductIndexer.php @@ -7,11 +7,14 @@ namespace Aligent\Prerender\Model\Indexer\Category; +use Aligent\Prerender\Api\Data\PrerenderRecachingManagementRequestInterfaceFactory + as PrerenderRecachingManagementRequest; use Aligent\Prerender\Api\PrerenderClientInterface; use Aligent\Prerender\Helper\Config; use Aligent\Prerender\Model\Indexer\DataProvider\ProductCategories; use Aligent\Prerender\Model\Url\GetUrlsForCategories; use Magento\ConfigurableProduct\Model\Product\Type\Configurable; +use Magento\AsynchronousOperations\Model\MassSchedule; use Magento\Framework\App\DeploymentConfig; use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Exception\LocalizedException; @@ -20,6 +23,7 @@ use Magento\Framework\Indexer\DimensionalIndexerInterface; use Magento\Framework\Indexer\DimensionProviderInterface; use Magento\Framework\Mview\ActionInterface as MviewActionInterface; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Store\Model\StoreDimensionProvider; class ProductIndexer implements IndexerActionInterface, MviewActionInterface, DimensionalIndexerInterface @@ -27,20 +31,6 @@ class ProductIndexer implements IndexerActionInterface, MviewActionInterface, Di private const INDEXER_ID = 'prerender_category_product'; private const DEPLOYMENT_CONFIG_INDEXER_BATCHES = 'indexer/batch_size/'; - /** @var DimensionProviderInterface */ - private DimensionProviderInterface $dimensionProvider; - /** @var ProductCategories */ - private ProductCategories $productCategoriesDataProvider; - /** @var GetUrlsForCategories */ - private GetUrlsForCategories $getUrlsForCategories; - /** @var PrerenderClientInterface */ - private PrerenderClientInterface $prerenderClient; - /** @var DeploymentConfig */ - private DeploymentConfig $eploymentConfig; - /** @var Config */ - private Config $prerenderConfigHelper; - /** @var Configurable */ - private Configurable $configurable; /** @var int|null */ private ?int $batchSize; @@ -53,26 +43,25 @@ class ProductIndexer implements IndexerActionInterface, MviewActionInterface, Di * @param DeploymentConfig $deploymentConfig * @param Config $prerenderConfigHelper * @param Configurable $configurable + * @param PrerenderRecachingManagementRequest $prerenderRecachingManagementRequest + * @param MassSchedule $massSchedule + * @param Json $json * @param int|null $batchSize */ public function __construct( - DimensionProviderInterface $dimensionProvider, - ProductCategories $productCategoriesDataProvider, - GetUrlsForCategories $getUrlsForCategories, - PrerenderClientInterface $prerenderClient, - DeploymentConfig $deploymentConfig, - Config $prerenderConfigHelper, - Configurable $configurable, + private readonly DimensionProviderInterface $dimensionProvider, + private readonly ProductCategories $productCategoriesDataProvider, + private readonly GetUrlsForCategories $getUrlsForCategories, + private readonly PrerenderClientInterface $prerenderClient, + private readonly DeploymentConfig $deploymentConfig, + private readonly Config $prerenderConfigHelper, + private readonly Configurable $configurable, + private readonly PrerenderRecachingManagementRequest $prerenderRecachingManagementRequest, + private readonly MassSchedule $massSchedule, + private readonly Json $json, ?int $batchSize = 1000 ) { - $this->dimensionProvider = $dimensionProvider; - $this->productCategoriesDataProvider = $productCategoriesDataProvider; - $this->getUrlsForCategories = $getUrlsForCategories; - $this->prerenderClient = $prerenderClient; - $this->deploymentConfig = $deploymentConfig; $this->batchSize = $batchSize; - $this->prerenderConfigHelper = $prerenderConfigHelper; - $this->configurable = $configurable; } /** @@ -141,7 +130,9 @@ public function execute($ids): void public function executeByDimensions(array $dimensions, \Traversable $entityIds): void { if (count($dimensions) > 1 || !isset($dimensions[StoreDimensionProvider::DIMENSION_NAME])) { - throw new \InvalidArgumentException('Indexer "' . self::INDEXER_ID . '" supports only Store dimension'); + throw new \InvalidArgumentException( + 'Indexer "' . self::INDEXER_ID . '" supports only Store dimension' + ); } $storeId = (int)$dimensions[StoreDimensionProvider::DIMENSION_NAME]->getValue(); @@ -154,7 +145,7 @@ public function executeByDimensions(array $dimensions, \Traversable $entityIds): // Include configurable product id(s) if the edited product is simple $parentIds = $this->configurable->getParentIdsByChild($entityIds); $entityIds = array_unique(array_merge($entityIds, $parentIds)); - + // get list of category ids for the products $categoryIds = $this->productCategoriesDataProvider->getCategoryIdsForProducts($entityIds, $storeId); @@ -167,7 +158,11 @@ public function executeByDimensions(array $dimensions, \Traversable $entityIds): $urlBatches = array_chunk($urls, $this->batchSize); foreach ($urlBatches as $batchUrls) { - $this->prerenderClient->recacheUrls($batchUrls, $storeId); + $request = $this->prerenderRecachingManagementRequest->create(); + $request->setBatchUrls($this->json->serialize($batchUrls)); + $request->setStoreId((int) $storeId); + $request->setIndexerId(self::INDEXER_ID); + $this->massSchedule->publishMass('asynchronous.prerender.recaching', [[$request]]); } } } diff --git a/Model/Indexer/DataProvider/ProductCategories.php b/Model/Indexer/DataProvider/ProductCategories.php index 98f708e..713557a 100644 --- a/Model/Indexer/DataProvider/ProductCategories.php +++ b/Model/Indexer/DataProvider/ProductCategories.php @@ -13,21 +13,14 @@ class ProductCategories { - /** @var ProductCollectionFactory */ - private ProductCollectionFactory $productCollectionFactory; - /** @var CategoryCollectionFactory */ - private CategoryCollectionFactory $categoryCollectionFactory; - /** * @param ProductCollectionFactory $productCollectionFactory * @param CategoryCollectionFactory $categoryCollectionFactory */ public function __construct( - ProductCollectionFactory $productCollectionFactory, - CategoryCollectionFactory $categoryCollectionFactory + private readonly ProductCollectionFactory $productCollectionFactory, + private readonly CategoryCollectionFactory $categoryCollectionFactory ) { - $this->productCollectionFactory = $productCollectionFactory; - $this->categoryCollectionFactory = $categoryCollectionFactory; } /** diff --git a/Model/Indexer/Product/ProductIndexer.php b/Model/Indexer/Product/ProductIndexer.php index e5493e6..ea15c0c 100644 --- a/Model/Indexer/Product/ProductIndexer.php +++ b/Model/Indexer/Product/ProductIndexer.php @@ -7,10 +7,13 @@ namespace Aligent\Prerender\Model\Indexer\Product; +use Aligent\Prerender\Api\Data\PrerenderRecachingManagementRequestInterfaceFactory + as PrerenderRecachingManagementRequest; use Aligent\Prerender\Api\PrerenderClientInterface; use Aligent\Prerender\Helper\Config; use Aligent\Prerender\Model\Url\GetUrlsForProducts; use Magento\ConfigurableProduct\Model\Product\Type\Configurable; +use Magento\AsynchronousOperations\Model\MassSchedule; use Magento\Framework\App\DeploymentConfig; use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Exception\LocalizedException; @@ -19,6 +22,7 @@ use Magento\Framework\Indexer\DimensionalIndexerInterface; use Magento\Framework\Indexer\DimensionProviderInterface; use Magento\Framework\Mview\ActionInterface as MviewActionInterface; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Store\Model\StoreDimensionProvider; class ProductIndexer implements IndexerActionInterface, MviewActionInterface, DimensionalIndexerInterface @@ -26,18 +30,6 @@ class ProductIndexer implements IndexerActionInterface, MviewActionInterface, Di private const INDEXER_ID = 'prerender_product'; private const DEPLOYMENT_CONFIG_INDEXER_BATCHES = 'indexer/batch_size/'; - /** @var DimensionProviderInterface */ - private DimensionProviderInterface $dimensionProvider; - /** @var GetUrlsForProducts */ - private GetUrlsForProducts $getUrlsForProducts; - /** @var PrerenderClientInterface */ - private PrerenderClientInterface $prerenderClient; - /** @var DeploymentConfig */ - private DeploymentConfig $deploymentConfig; - /** @var Config */ - private Config $prerenderConfigHelper; - /** @var Configurable */ - private Configurable $configurable; /** @var int|null */ private ?int $batchSize; @@ -49,24 +41,24 @@ class ProductIndexer implements IndexerActionInterface, MviewActionInterface, Di * @param DeploymentConfig $deploymentConfig * @param Config $prerenderConfigHelper * @param Configurable $configurable + * @param PrerenderRecachingManagementRequest $prerenderRecachingManagementRequest + * @param MassSchedule $massSchedule + * @param Json $json * @param int|null $batchSize */ public function __construct( - DimensionProviderInterface $dimensionProvider, - GetUrlsForProducts $getUrlsForProducts, - PrerenderClientInterface $prerenderClient, - DeploymentConfig $deploymentConfig, - Config $prerenderConfigHelper, - Configurable $configurable, + private readonly DimensionProviderInterface $dimensionProvider, + private readonly GetUrlsForProducts $getUrlsForProducts, + private readonly PrerenderClientInterface $prerenderClient, + private readonly DeploymentConfig $deploymentConfig, + private readonly Config $prerenderConfigHelper, + private readonly Configurable $configurable, + private readonly PrerenderRecachingManagementRequest $prerenderRecachingManagementRequest, + private readonly MassSchedule $massSchedule, + private readonly Json $json, ?int $batchSize = 1000 ) { - $this->dimensionProvider = $dimensionProvider; - $this->getUrlsForProducts = $getUrlsForProducts; - $this->prerenderClient = $prerenderClient; - $this->deploymentConfig = $deploymentConfig; $this->batchSize = $batchSize; - $this->prerenderConfigHelper = $prerenderConfigHelper; - $this->configurable = $configurable; } /** @@ -135,7 +127,9 @@ public function execute($ids): void public function executeByDimensions(array $dimensions, \Traversable $entityIds): void { if (count($dimensions) > 1 || !isset($dimensions[StoreDimensionProvider::DIMENSION_NAME])) { - throw new \InvalidArgumentException('Indexer "' . self::INDEXER_ID . '" supports only Store dimension'); + throw new \InvalidArgumentException( + 'Indexer "' . self::INDEXER_ID . '" supports only Store dimension' + ); } $storeId = (int)$dimensions[StoreDimensionProvider::DIMENSION_NAME]->getValue(); @@ -147,7 +141,7 @@ public function executeByDimensions(array $dimensions, \Traversable $entityIds): $parentIds = $this->configurable->getParentIdsByChild($entityIds); $entityIds = array_unique(array_merge($entityIds, $parentIds)); - + // get urls for the products $urls = $this->getUrlsForProducts->execute($entityIds, $storeId); @@ -157,7 +151,11 @@ public function executeByDimensions(array $dimensions, \Traversable $entityIds): $urlBatches = array_chunk($urls, $this->batchSize); foreach ($urlBatches as $batchUrls) { - $this->prerenderClient->recacheUrls($batchUrls, $storeId); + $request = $this->prerenderRecachingManagementRequest->create(); + $request->setBatchUrls($this->json->serialize($batchUrls)); + $request->setStoreId((int) $storeId); + $request->setIndexerId(self::INDEXER_ID); + $this->massSchedule->publishMass('asynchronous.prerender.recaching', [[$request]]); } } } diff --git a/Model/Url/GetUrlsForCategories.php b/Model/Url/GetUrlsForCategories.php index e8696d5..27e1b0f 100644 --- a/Model/Url/GetUrlsForCategories.php +++ b/Model/Url/GetUrlsForCategories.php @@ -18,16 +18,6 @@ class GetUrlsForCategories { private const DELIMETER = "?"; - /** @var CollectionFactory */ - private CollectionFactory $categoryCollectionFactory; - /** @var StoreManagerInterface */ - private StoreManagerInterface $storeManager; - /** @var Emulation */ - private Emulation $emulation; - - /** @var Url */ - private Url $url; - /** * * @param CollectionFactory $categoryCollectionFactory @@ -35,15 +25,11 @@ class GetUrlsForCategories * @param Emulation $emulation */ public function __construct( - CollectionFactory $categoryCollectionFactory, - StoreManagerInterface $storeManager, - Emulation $emulation, - Url $url + private readonly CollectionFactory $categoryCollectionFactory, + private readonly StoreManagerInterface $storeManager, + private readonly Emulation $emulation, + private readonly Url $url ) { - $this->categoryCollectionFactory = $categoryCollectionFactory; - $this->storeManager = $storeManager; - $this->emulation = $emulation; - $this->url = $url; } /** diff --git a/Model/Url/GetUrlsForProducts.php b/Model/Url/GetUrlsForProducts.php index e2ba4b6..e8a6070 100644 --- a/Model/Url/GetUrlsForProducts.php +++ b/Model/Url/GetUrlsForProducts.php @@ -18,16 +18,6 @@ class GetUrlsForProducts { private const DELIMETER = "?"; - /** @var CollectionFactory */ - private CollectionFactory $productCollectionFactory; - /** @var StoreManagerInterface */ - private StoreManagerInterface $storeManager; - /** @var Emulation */ - private Emulation $emulation; - - /** @var Url */ - private Url $url; - /** * * @param CollectionFactory $productCollectionFactory @@ -35,15 +25,11 @@ class GetUrlsForProducts * @param Emulation $emulation */ public function __construct( - CollectionFactory $productCollectionFactory, - StoreManagerInterface $storeManager, - Emulation $emulation, - Url $url + private readonly CollectionFactory $productCollectionFactory, + private readonly StoreManagerInterface $storeManager, + private readonly Emulation $emulation, + private readonly Url $url ) { - $this->productCollectionFactory = $productCollectionFactory; - $this->storeManager = $storeManager; - $this->emulation = $emulation; - $this->url = $url; } /** diff --git a/composer.json b/composer.json index 1bbd369..cd24703 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "aligent/magento2-prerender", "description": "Prerender service integration for Magento 2, providing recaching for product URLs", "require": { - "php": ">=7.4", + "php": ">=8.1", "magento/framework": "*", "magento/module-store": "*", "magento/module-catalog": "*", diff --git a/etc/communication.xml b/etc/communication.xml new file mode 100644 index 0000000..9ca0106 --- /dev/null +++ b/etc/communication.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/etc/di.xml b/etc/di.xml index 885028d..a0073c9 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -7,6 +7,10 @@ xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + + diff --git a/etc/queue_consumer.xml b/etc/queue_consumer.xml new file mode 100644 index 0000000..b0b0f10 --- /dev/null +++ b/etc/queue_consumer.xml @@ -0,0 +1,10 @@ + + + + diff --git a/etc/queue_publisher.xml b/etc/queue_publisher.xml new file mode 100644 index 0000000..c2ac266 --- /dev/null +++ b/etc/queue_publisher.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/etc/queue_topology.xml b/etc/queue_topology.xml new file mode 100644 index 0000000..bd53ad1 --- /dev/null +++ b/etc/queue_topology.xml @@ -0,0 +1,10 @@ + + + + + +