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

Try implementing interface #320

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
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
282 changes: 137 additions & 145 deletions Model/ProductRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@
use Magento\Catalog\Helper\Image as ImageHelper;
use Magento\Catalog\Helper\ImageFactory;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ProductRepository as ProductRepositoryBase;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest using a factory instead using a factory instead of the repository itself

use Magento\Catalog\Model\ResourceModel\Product as ProductResourceModel;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Api\SearchCriteriaInterface;
use Magento\Framework\App\Area;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Store\Model\App\Emulation;
use Magento\Store\Api\StoreConfigManagerInterface as MagentoStoreConfig;
use Magento\Store\Model\App\Emulation;
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 @@ -24,22 +27,62 @@
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class ProductRepository extends \Magento\Catalog\Model\ProductRepository
class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterface
{
private $imageHelperFactory;
private $appEmulation;
private $cacheLimit = 0;
private $productHelperFactory;
private $priceHelperFactory;
private $inventoryHelperFactory;
private $storeConfig;
private $magentoStoreConfig;
private $categoryList;

/**
* List of custom attributes we want to exclude from indexation
*/
const EXCLUDED_CUSTOM_ATTRIBUTES = ['special_price', 'special_from_date', 'special_to_date'];
protected $imageHelperFactory;
protected $appEmulation;
protected $categoryListInterface;
protected $productHelperFactory;
protected $priceHelperFactory;
protected $inventoryHelperFactory;
protected $storeConfig;
protected $magentoStoreConfig;
protected $productFactory;
protected $searchCriteriaBuilder;
protected $resourceModel;
protected $storeManager;
protected $productRepositoryBase;
protected $cacheLimit;
protected $instances;
protected $instancesById;
protected $excludedCustomAttributes;


public function __construct(
ImageFactory $imageHelperFactory,
Emulation $appEmulation,
CategoryListInterface $categoryListInterface,
ProductHelperFactory $productHelperFactory,
PriceHelperFactory $priceHelperFactory,
InventoryHelperFactory $inventoryHelperFactory,
StoreConfig $storeConfig,
MagentoStoreConfig $magentoStoreConfig,
ProductHelperFactory $productFactory,
SearchCriteriaBuilder $searchCriteriaBuilder,
ProductResourceModel $resourceModel,
StoreManagerInterface $storeManager,
ProductRepositoryBase $productRepositoryBase,
$cacheLimit = 1000
) {
$this->imageHelperFactory = $imageHelperFactory;
$this->appEmulation = $appEmulation;
$this->categoryListInterface = $categoryListInterface;
$this->productHelperFactory = $productHelperFactory;
$this->priceHelperFactory = $priceHelperFactory;
$this->inventoryHelperFactory = $inventoryHelperFactory;
$this->storeConfig = $storeConfig;
$this->magentoStoreConfig = $magentoStoreConfig;
$this->productFactory = $productFactory;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->resourceModel = $resourceModel;
$this->storeManager = $storeManager;
$this->productRepositoryBase = $productRepositoryBase;
$this->cacheLimit = $cacheLimit;
$this->instances = [];
$this->instancesById = [];
//Add here any custom attributes we want to exclude from indexation
$this->excludedCustomAttributes = ['special_price', 'special_from_date', 'special_to_date'];
}

/**
* @inheritDoc
Expand All @@ -66,11 +109,10 @@ public function get($sku, $editMode = false, $storeId = null, $forceReload = fal
$storeId = $this->storeManager->getStore()->getId();
}
$product->load($productId);
$appEmulation = $this->getAppEmulation();
$appEmulation->startEnvironmentEmulation($storeId, Area::AREA_FRONTEND, true);
$this->appEmulation->startEnvironmentEmulation($storeId, Area::AREA_FRONTEND, true);
$this->setExtensionAttributes($product, $storeId);
$this->setCustomAttributes($product);
$appEmulation->stopEnvironmentEmulation();
$this->appEmulation->stopEnvironmentEmulation();
// End Custom code here
$this->cacheProduct($cacheKey, $product);
$cachedProduct = $product;
Expand All @@ -84,36 +126,90 @@ public function get($sku, $editMode = false, $storeId = null, $forceReload = fal
*/
public function getList(SearchCriteriaInterface $searchCriteria)
{
$searchResult = parent::getList($searchCriteria);
$searchResult = $this->productRepositoryBase->getList($searchCriteria);
$storeId = null;

$appEmulation = $this->getAppEmulation();
foreach ($searchResult->getItems() as $product) {
if ($storeId !== $product->getStoreId()) {
$storeId = $product->getStoreId();
$appEmulation->stopEnvironmentEmulation();
$appEmulation->startEnvironmentEmulation($storeId, Area::AREA_FRONTEND, true);
$this->appEmulation->stopEnvironmentEmulation();
$this->appEmulation->startEnvironmentEmulation($storeId, Area::AREA_FRONTEND, true);
}

$this->setExtensionAttributes($product, $storeId);
$this->setCustomAttributes($product);
}
$appEmulation->stopEnvironmentEmulation();
$this->appEmulation->stopEnvironmentEmulation();

return $searchResult;
}

/**
* {@inheritdoc}
*/
public function save(ProductInterface $product, $saveOptions = false) {
return $this->productRepositoryBase->save($product, $saveOptions);
}

/**
* {@inheritdoc}
*/
public function delete(ProductInterface $product) {
return $this->productRepositoryBase->delete($product);
}

/**
* {@inheritdoc}
*/
public function getById($productId, $editMode = false, $storeId = null, $forceReload = false) {
return $this->productRepositoryBase->getById($productId, $editMode, $storeId, $forceReload);
}

/**
* {@inheritdoc}
*/
public function deleteById($sku)
{
return $this->productRepositoryBase->deleteById($sku);
}

/**
* Get key for cache
*
* @param array $data
* @return string
*/
public function getCacheKey($data)
{
$serializeData = [];
foreach ($data as $key => $value) {
if (is_object($value)) {
$serializeData[$key] = $value->getId();
} else {
$serializeData[$key] = $value;
}
}

return md5(serialize($serializeData));
}

public function _resetState()
{
$this->instances = [];
$this->instancesById = [];
}

/**
* Retrieve product image
*
* @param Product $product
* @param string $imageId
* @param array $attributes
* @param array|null $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->getImageHelperFactory()->create()->init($product, $imageId, $attributes);
return $this->imageHelperFactory->create()->init($product, $imageId, $attributes);
}

/**
Expand All @@ -122,9 +218,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->getProductHelperFactory()->create()->getProductUrl($product);
return $this->productHelperFactory->create()->getProductUrl($product);
}

/**
Expand Down Expand Up @@ -194,8 +290,8 @@ private function prepareSku(string $sku): string
*/
private function setCustomAttributes($product): void
{
$productHelper = $this->getProductHelperFactory()->create();
$customAttributes = $this->getStoreConfig()->getCustomAttributes($product->getStoreId());
$productHelper = $this->productHelperFactory->create();
$customAttributes = $this->storeConfig->getCustomAttributes($product->getStoreId());

foreach ($customAttributes as $customAttribute) {
$code = $customAttribute['code'];
Expand Down Expand Up @@ -227,9 +323,9 @@ private function setCustomAttributes($product): void
*/
private function setExtensionAttributes($product, $storeId): void
{
$priceHelper = $this->getPriceHelperFactory()->create();
$productHelper = $this->getProductHelperFactory()->create();
$inventoryHelper = $this->getInventoryHelperFactory()->create();
$priceHelper = $this->priceHelperFactory->create();
$productHelper = $this->productHelperFactory->create();
$inventoryHelper = $this->inventoryHelperFactory->create();
$storeCode = $this->storeManager->getStore($storeId)->getCode();

/** @var ProductExtension $extensionAttributes */
Expand All @@ -240,9 +336,9 @@ private function setExtensionAttributes($product, $storeId): void

$extensionAttributes->setUrlFull($this->getProductUrl($product));
$extensionAttributes->setIsInStock($stockAndStatus[1]);
$extensionAttributes->setBaseUrl($this->getMagentoStoreConfig()->getStoreConfigs([$storeCode])[0]->getBaseUrl());
$extensionAttributes->setBaseUrl($this->magentoStoreConfig->getStoreConfigs([$storeCode])[0]->getBaseUrl());
$extensionAttributes->setBaseMediaUrl(
$this->getMagentoStoreConfig()->getStoreConfigs([$storeCode])[0]->getBaseMediaUrl()
$this->magentoStoreConfig->getStoreConfigs([$storeCode])[0]->getBaseMediaUrl()
);

$categories = $extensionAttributes->getCategoryLinks();
Expand All @@ -266,9 +362,9 @@ private function setExtensionAttributes($product, $storeId): void
* @param ProductInterface $product
* @return void
*/
public function removeExcludedCustomAttributes($product): void
public function removeExcludedCustomAttributes($product)
{
foreach (self::EXCLUDED_CUSTOM_ATTRIBUTES as $attribute) {
foreach ($this->excludedCustomAttributes as $attribute) {
if (isset($product[$attribute])) {
unset($product[$attribute]);
}
Expand All @@ -285,7 +381,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 @@ -313,7 +409,7 @@ private function getCategoriesInformation($categories)
->addFilter('is_active', '1')
->create();

$categories = $this->getCategoryList()->getList($searchCriteria)->__toArray();
$categories = $this->categoryListInterface->getList($searchCriteria)->__toArray();

// Get just the information needed in order to make the response lighter
$categoryResults = [];
Expand All @@ -328,108 +424,4 @@ 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->inventoryHelperFactory;
}

/**
* 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;
}
}
Loading