Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatible with Magento 2.4.7, as backward compatibility has been lost in the Magento\Catalog\Model\ProductRepository class #318

Merged
merged 2 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
259 changes: 136 additions & 123 deletions Model/ProductRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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;
Expand All @@ -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;
}
Expand All @@ -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);
}

/**
Expand All @@ -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);
}

/**
Expand Down Expand Up @@ -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'];
Expand Down Expand Up @@ -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 */
Expand All @@ -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();
Expand All @@ -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]);
}
Expand All @@ -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');

Expand Down Expand Up @@ -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 = [];
Expand All @@ -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;
davidmolinacano marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* 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;
}
}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
2 changes: 1 addition & 1 deletion etc/module.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Doofinder_Feed" setup_version="0.13.13">
<module name="Doofinder_Feed" setup_version="0.13.14">
<sequence>
<module name="Magento_Integration" />
</sequence>
Expand Down