From 20392581b98b5c5a6fcee7780638827211d173a0 Mon Sep 17 00:00:00 2001 From: Tu Van Date: Fri, 10 May 2024 10:53:55 +0700 Subject: [PATCH 1/2] Compatible with Magento 2.4.7, as backward compatibility has been lost in the Magento\Catalog\Model\ProductRepository class Check the issue page in the Magento repo for reference: https://github.com/magento/magento2/issues/38669 --- Model/ProductRepository.php | 259 +++++++++++++++++++----------------- composer.json | 2 +- etc/module.xml | 2 +- 3 files changed, 138 insertions(+), 125 deletions(-) diff --git a/Model/ProductRepository.php b/Model/ProductRepository.php index fed308c0..32bf07ff 100644 --- a/Model/ProductRepository.php +++ b/Model/ProductRepository.php @@ -6,38 +6,16 @@ use Magento\Catalog\Api\Data\ProductExtension; use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Catalog\Api\Data\ProductSearchResultsInterfaceFactory; use Magento\Catalog\Api\CategoryListInterface; -use Magento\Catalog\Api\ProductAttributeRepositoryInterface; -use Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper; use Magento\Catalog\Helper\Image as ImageHelper; use Magento\Catalog\Helper\ImageFactory; use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\Product\Gallery\MimeTypeExtensionMap; -use Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks; -use Magento\Catalog\Model\Product\LinkTypeProvider as ProductLinkTypeProvider; -use Magento\Catalog\Model\Product\Option\Converter as ProductOptionConverter; -use Magento\Catalog\Model\ProductFactory; -use Magento\Catalog\Model\ResourceModel\Product as ProductResourceModel; -use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory; -use Magento\CatalogInventory\Api\StockRegistryInterface; -use Magento\Framework\Api\Data\ImageContentInterfaceFactory; -use Magento\Framework\Api\ExtensibleDataObjectConverter; -use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; -use Magento\Framework\Api\FilterBuilder as ApiFilterBuilder; -use Magento\Framework\Api\ImageContentValidatorInterface; -use Magento\Framework\Api\ImageProcessorInterface; -use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; -use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\App\Area; -use Magento\Framework\EntityManager\Operation\Read\ReadExtensions; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\Filesystem; -use Magento\Framework\Serialize\Serializer\Json as JsonSerializer; use Magento\Store\Model\App\Emulation; use Magento\Store\Api\StoreConfigManagerInterface as MagentoStoreConfig; -use Magento\Store\Model\StoreManagerInterface; use Doofinder\Feed\Helper\ProductFactory as ProductHelperFactory; use Doofinder\Feed\Helper\PriceFactory as PriceHelperFactory; use Doofinder\Feed\Helper\InventoryFactory as InventoryHelperFactory; @@ -48,91 +26,20 @@ */ class ProductRepository extends \Magento\Catalog\Model\ProductRepository { - protected $imageHelperFactory; - protected $appEmulation; - private $stockRegistry; + private $imageHelperFactory; + private $appEmulation; private $cacheLimit = 0; private $productHelperFactory; private $priceHelperFactory; private $inventoryHelperFactory; private $storeConfig; private $magentoStoreConfig; - private $excludedCustomAttributes; - private $categoryListInterface; - - public function __construct( - ImageFactory $imageHelperFactory, - Emulation $appEmulation, - StockRegistryInterface $stockRegistry, - CategoryListInterface $categoryListInterface, - ProductHelperFactory $productHelperFactory, - PriceHelperFactory $priceHelperFactory, - InventoryHelperFactory $inventoryHelperFactory, - StoreConfig $storeConfig, - MagentoStoreConfig $magentoStoreConfig, - ProductFactory $productFactory, - Helper $initializationHelper, - ProductSearchResultsInterfaceFactory $searchResultsFactory, - ProductCollectionFactory $collectionFactory, - SearchCriteriaBuilder $searchCriteriaBuilder, - ProductAttributeRepositoryInterface $attributeRepository, - ProductResourceModel $resourceModel, - ProductLinks $linkInitializer, - ProductLinkTypeProvider $linkTypeProvider, - StoreManagerInterface $storeManager, - ApiFilterBuilder $filterBuilder, - ProductAttributeRepositoryInterface $metadataServiceInterface, - ExtensibleDataObjectConverter $extensibleDataObjectConverter, - ProductOptionConverter $optionConverter, - Filesystem $fileSystem, - ImageContentValidatorInterface $contentValidator, - ImageContentInterfaceFactory $contentFactory, - MimeTypeExtensionMap $mimeTypeExtensionMap, - ImageProcessorInterface $imageProcessor, - JoinProcessorInterface $extensionAttributesJoinProcessor, - CollectionProcessorInterface $collectionProcessor = null, - JsonSerializer $serializer = null, - $cacheLimit = 1000, - ReadExtensions $readExtensions = null - ) { - $this->imageHelperFactory = $imageHelperFactory; - $this->appEmulation = $appEmulation; - $this->stockRegistry = $stockRegistry; - $this->categoryListInterface = $categoryListInterface; - $this->productHelperFactory = $productHelperFactory; - $this->priceHelperFactory = $priceHelperFactory; - $this->inventoryHelperFactory = $inventoryHelperFactory; - $this->storeConfig = $storeConfig; - $this->magentoStoreConfig = $magentoStoreConfig; - //Add here any custom attributes we want to exclude from indexation - $this->excludedCustomAttributes = ['special_price', 'special_from_date', 'special_to_date']; - parent::__construct( - $productFactory, - $initializationHelper, - $searchResultsFactory, - $collectionFactory, - $searchCriteriaBuilder, - $attributeRepository, - $resourceModel, - $linkInitializer, - $linkTypeProvider, - $storeManager, - $filterBuilder, - $metadataServiceInterface, - $extensibleDataObjectConverter, - $optionConverter, - $fileSystem, - $contentValidator, - $contentFactory, - $mimeTypeExtensionMap, - $imageProcessor, - $extensionAttributesJoinProcessor, - $collectionProcessor, - $serializer, - $cacheLimit, - $readExtensions - ); - } + private $categoryList; + + /** + * List of custom attributes we want to exclude from indexation + */ + const EXCLUDED_CUSTOM_ATTRIBUTES = ['special_price', 'special_from_date', 'special_to_date']; /** * @inheritDoc @@ -159,10 +66,11 @@ public function get($sku, $editMode = false, $storeId = null, $forceReload = fal $storeId = $this->storeManager->getStore()->getId(); } $product->load($productId); - $this->appEmulation->startEnvironmentEmulation($storeId, Area::AREA_FRONTEND, true); + $appEmulation = $this->getAppEmulation(); + $appEmulation->startEnvironmentEmulation($storeId, Area::AREA_FRONTEND, true); $this->setExtensionAttributes($product, $storeId); $this->setCustomAttributes($product); - $this->appEmulation->stopEnvironmentEmulation(); + $appEmulation->stopEnvironmentEmulation(); // End Custom code here $this->cacheProduct($cacheKey, $product); $cachedProduct = $product; @@ -179,17 +87,18 @@ public function getList(SearchCriteriaInterface $searchCriteria) $searchResult = parent::getList($searchCriteria); $storeId = null; + $appEmulation = $this->getAppEmulation(); foreach ($searchResult->getItems() as $product) { if ($storeId !== $product->getStoreId()) { $storeId = $product->getStoreId(); - $this->appEmulation->stopEnvironmentEmulation(); - $this->appEmulation->startEnvironmentEmulation($storeId, Area::AREA_FRONTEND, true); + $appEmulation->stopEnvironmentEmulation(); + $appEmulation->startEnvironmentEmulation($storeId, Area::AREA_FRONTEND, true); } $this->setExtensionAttributes($product, $storeId); $this->setCustomAttributes($product); } - $this->appEmulation->stopEnvironmentEmulation(); + $appEmulation->stopEnvironmentEmulation(); return $searchResult; } @@ -199,12 +108,12 @@ public function getList(SearchCriteriaInterface $searchCriteria) * * @param Product $product * @param string $imageId - * @param array|null $attributes + * @param array $attributes * @return ImageHelper */ - private function getImage(Product $product, string $imageId, ?array $attributes = []): ImageHelper + private function getImage(Product $product, string $imageId, array $attributes = []): ImageHelper { - return $this->imageHelperFactory->create()->init($product, $imageId, $attributes); + return $this->getImageHelperFactory()->create()->init($product, $imageId, $attributes); } /** @@ -213,9 +122,9 @@ private function getImage(Product $product, string $imageId, ?array $attributes * @param Product $product * @return String */ - private function getProductUrl(Product $product): String + private function getProductUrl(Product $product): string { - return $this->productHelperFactory->create()->getProductUrl($product); + return $this->getProductHelperFactory()->create()->getProductUrl($product); } /** @@ -285,8 +194,8 @@ private function prepareSku(string $sku): string */ private function setCustomAttributes($product): void { - $productHelper = $this->productHelperFactory->create(); - $customAttributes = $this->storeConfig->getCustomAttributes($product->getStoreId()); + $productHelper = $this->getProductHelperFactory()->create(); + $customAttributes = $this->getStoreConfig()->getCustomAttributes($product->getStoreId()); foreach ($customAttributes as $customAttribute) { $code = $customAttribute['code']; @@ -318,9 +227,9 @@ private function setCustomAttributes($product): void */ private function setExtensionAttributes($product, $storeId): void { - $priceHelper = $this->priceHelperFactory->create(); - $productHelper = $this->productHelperFactory->create(); - $inventoryHelper = $this->inventoryHelperFactory->create(); + $priceHelper = $this->getPriceHelperFactory()->create(); + $productHelper = $this->getProductHelperFactory()->create(); + $inventoryHelper = $this->getInventoryHelperFactory()->create(); $storeCode = $this->storeManager->getStore($storeId)->getCode(); /** @var ProductExtension $extensionAttributes */ @@ -331,9 +240,9 @@ private function setExtensionAttributes($product, $storeId): void $extensionAttributes->setUrlFull($this->getProductUrl($product)); $extensionAttributes->setIsInStock($stockAndStatus[1]); - $extensionAttributes->setBaseUrl($this->magentoStoreConfig->getStoreConfigs([$storeCode])[0]->getBaseUrl()); + $extensionAttributes->setBaseUrl($this->getMagentoStoreConfig()->getStoreConfigs([$storeCode])[0]->getBaseUrl()); $extensionAttributes->setBaseMediaUrl( - $this->magentoStoreConfig->getStoreConfigs([$storeCode])[0]->getBaseMediaUrl() + $this->getMagentoStoreConfig()->getStoreConfigs([$storeCode])[0]->getBaseMediaUrl() ); $categories = $extensionAttributes->getCategoryLinks(); @@ -357,9 +266,9 @@ private function setExtensionAttributes($product, $storeId): void * @param ProductInterface $product * @return void */ - public function removeExcludedCustomAttributes($product) + public function removeExcludedCustomAttributes($product): void { - foreach ($this->excludedCustomAttributes as $attribute) { + foreach (self::EXCLUDED_CUSTOM_ATTRIBUTES as $attribute) { if (isset($product[$attribute])) { unset($product[$attribute]); } @@ -376,7 +285,7 @@ private function getCategoriesInformation($categories) $categoryIds[$category->getCategoryId()] = true; } } - + // Get table name with prefix if it exists $catalogCategoryEntityTable = $this->resourceModel->getTable('catalog_category_entity'); @@ -404,7 +313,7 @@ private function getCategoriesInformation($categories) ->addFilter('is_active', '1') ->create(); - $categories = $this->categoryListInterface->getList($searchCriteria)->__toArray(); + $categories = $this->getCategoryList()->getList($searchCriteria)->__toArray(); // Get just the information needed in order to make the response lighter $categoryResults = []; @@ -419,4 +328,108 @@ private function getCategoriesInformation($categories) return $categoryResults; } + + /** + * Get the ImageFactory instance + * + * @return ImageFactory + */ + private function getImageHelperFactory(): ImageFactory + { + if ($this->imageHelperFactory === null) { + $this->imageHelperFactory = ObjectManager::getInstance()->get(ImageFactory::class); + } + return $this->imageHelperFactory; + } + + /** + * Get the ProductHelperFactory instance + * + * @return ProductHelperFactory + */ + private function getProductHelperFactory(): ProductHelperFactory + { + if ($this->productHelperFactory === null) { + $this->productHelperFactory = ObjectManager::getInstance()->get(ProductHelperFactory::class); + } + return $this->productHelperFactory; + } + + /** + * Get the PriceHelperFactory instance + * + * @return PriceHelperFactory + */ + private function getPriceHelperFactory(): PriceHelperFactory + { + if ($this->priceHelperFactory === null) { + $this->priceHelperFactory = ObjectManager::getInstance()->get(PriceHelperFactory::class); + } + return $this->priceHelperFactory; + } + + /** + * Get the InventoryHelperFactory instance + * + * @return InventoryHelperFactory + */ + private function getInventoryHelperFactory(): InventoryHelperFactory + { + if ($this->inventoryHelperFactory === null) { + $this->inventoryHelperFactory = ObjectManager::getInstance()->get(InventoryHelperFactory::class); + } + return $this->inventoryHelper; + } + + /** + * Get the StoreConfig instance + * + * @return StoreConfig + */ + private function getStoreConfig(): StoreConfig + { + if ($this->storeConfig === null) { + $this->storeConfig = ObjectManager::getInstance()->get(StoreConfig::class); + } + return $this->storeConfig; + } + + /** + * Get the CategoryListInterface instance + * + * @return CategoryListInterface + */ + private function getCategoryList(): CategoryListInterface + { + if ($this->categoryList === null) { + $this->categoryList = ObjectManager::getInstance()->get(CategoryListInterface::class); + } + return $this->categoryList; + } + + /** + * Get the MagentoStoreConfig instance + * + * @return MagentoStoreConfig + */ + private function getMagentoStoreConfig(): MagentoStoreConfig + { + if ($this->magentoStoreConfig === null) { + $this->magentoStoreConfig = ObjectManager::getInstance()->get(MagentoStoreConfig::class); + } + return $this->magentoStoreConfig; + } + + /** + * Get the Emulation instance + * + * @return Emulation + */ + private function getAppEmulation(): Emulation + { + if ($this->appEmulation === null) { + $this->appEmulation = ObjectManager::getInstance()->get(Emulation::class); + } + return $this->appEmulation; + } } diff --git a/composer.json b/composer.json index 8e4a74f3..337389ab 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "doofinder/doofinder-magento2", - "version": "0.13.13", + "version": "0.13.14", "description": "Doofinder module for Magento 2", "type": "magento2-module", "require": { diff --git a/etc/module.xml b/etc/module.xml index 87c79fdf..4ea339e6 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,6 +1,6 @@ - + From 757e9c1627f96f059fd2dce9db747f3ad6a83e72 Mon Sep 17 00:00:00 2001 From: David Molina Cano <128705267+davidmolinacano@users.noreply.github.com> Date: Fri, 10 May 2024 10:56:21 +0200 Subject: [PATCH 2/2] Update Model/ProductRepository.php Changed inventoryHelper to inventoryHelperFactory Co-authored-by: sofia-doofinder <92720455+sofia-doofinder@users.noreply.github.com> --- Model/ProductRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Model/ProductRepository.php b/Model/ProductRepository.php index 32bf07ff..44deb79a 100644 --- a/Model/ProductRepository.php +++ b/Model/ProductRepository.php @@ -378,7 +378,7 @@ private function getInventoryHelperFactory(): InventoryHelperFactory if ($this->inventoryHelperFactory === null) { $this->inventoryHelperFactory = ObjectManager::getInstance()->get(InventoryHelperFactory::class); } - return $this->inventoryHelper; + return $this->inventoryHelperFactory; } /**