Skip to content

Commit

Permalink
Merge pull request Smile-SA#76 from Elastic-Suite/feat-optimize-thumb…
Browse files Browse the repository at this point in the history
…nail

[Autocomplete] Optimize thumbnail request
  • Loading branch information
romainruaud authored Oct 5, 2021
2 parents c5bcbb0 + e03f40e commit bd92d94
Showing 1 changed file with 146 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,61 +7,126 @@
* @category Smile
* @package Smile\ElasticsuiteInstantSearch
* @author Romain Ruaud <romain.ruaud@smile.fr>
* @copyright 2021 Smile
* @license Licensed to Smile-SA. All rights reserved. No warranty, explicit or implicit, provided.
* Unauthorized copying of this file, via any medium, is strictly prohibited.
* @copyright 2020 Smile
* @license Open Software License ("OSL") v. 3.0
*/

namespace Smile\ElasticsuiteInstantSearch\Model\Autocomplete\Product;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Helper\Image as ImageHelper;
use Magento\Catalog\Helper\ImageFactory as ImageHelperFactory;
use Magento\Framework\ObjectManagerInterface;
use Magento\Catalog\Api\ProductRepositoryInterfaceFactory;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Helper\Image;
use Magento\Catalog\Model\Product\Image\ParamsBuilder;
use Magento\Catalog\Model\ResourceModel\Product;
use Magento\Catalog\Model\View\Asset\Image as AssetImage;
use Magento\Catalog\Model\View\Asset\ImageFactory as AssetImageFactory;
use Magento\Catalog\Model\View\Asset\PlaceholderFactory;
use Magento\Framework\App\Area;
use Magento\Framework\App\CacheInterface;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Framework\View\Asset\Repository as AssetRepository;
use Magento\Framework\View\ConfigInterface;
use Magento\Framework\View\DesignInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Store\Model\StoreManagerInterfaceFactory;

/**
* Thumbnail helper for instant search.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*
* @category Smile
* @package Smile\ElasticsuiteInstantSearch
* @author Romain Ruaud <romain.ruaud@smile.fr>
*/
class ThumbnailHelper
{
/**
* @var ImageHelperFactory
* @var AsserImageFactory
*/
private $imageHelperFactory;
private $assetImageFactory;

/**
* @var ProductRepositoryInterfaceFactory
* @var DesignInterface
*/
private $productRepositoryFactory;
private $design;

/**
* @var ConfigInterface
*/
private $viewConfig;

/**
* @var StoreManagerInterfaceFactory
*/
private $storeManager;
private $storeManagerFactory;

/**
* @var ParamsBuilder
*/
private $paramsBuilder;

/**
* @var Product
*/
private $productResource;

/**
* @var PlaceholderFactory
*/
private $placeholderFactory;

/**
* @var AssetRepository
*/
private $assetRepository;

/**
* @var CacheInterface
*/
private $cache;

/**
* Constructor.
* @var SerializerInterface
*/
private $serializer;

/**
* Constructor
*
* @param ImageHelperFactory $imageHelperFactory Catalog product image helper.
* @param ProductRepositoryInterfaceFactory $productRepositoryFactory Product Repository
* @param StoreManagerInterfaceFactory $storeManagerFactory Store Manager
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*
* @param DesignInterface $design Design
* @param StoreManagerInterfaceFactory $storeManagerFactory Store Manager factory
* @param ConfigInterface $viewConfig View config
* @param ParamsBuilder $paramsBuilder Params builder
* @param Product $productResource Product Resource
* @param AssetRepository $assetRepository Asset Repository
* @param PlaceholderFactory $placeholderFactory Placeholder Factory
* @param AssetImageFactory $assetImageFactory Asset Image Factory
* @param CacheInterface $cache Cache
* @param SerializerInterface $serializer Serializer
*/
public function __construct(
ImageHelperFactory $imageHelperFactory,
ProductRepositoryInterfaceFactory $productRepositoryFactory,
StoreManagerInterfaceFactory $storeManagerFactory
DesignInterface $design,
StoreManagerInterfaceFactory $storeManagerFactory,
ConfigInterface $viewConfig,
ParamsBuilder $paramsBuilder,
Product $productResource,
AssetRepository $assetRepository,
PlaceholderFactory $placeholderFactory,
AssetImageFactory $assetImageFactory,
CacheInterface $cache,
SerializerInterface $serializer
) {
$this->imageHelperFactory = $imageHelperFactory;
$this->productRepositoryFactory = $productRepositoryFactory;
$this->storeManagerFactory = $storeManagerFactory;
$this->design = $design;
$this->storeManagerFactory = $storeManagerFactory;
$this->viewConfig = $viewConfig;
$this->paramsBuilder = $paramsBuilder;
$this->productResource = $productResource;
$this->placeholderFactory = $placeholderFactory;
$this->assetRepository = $assetRepository;
$this->assetImageFactory = $assetImageFactory;
$this->cache = $cache;
$this->serializer = $serializer;
}

/**
Expand All @@ -72,45 +137,82 @@ public function __construct(
*
* @return string
*/
public function getImageUrl($productId, $imageId = ItemFactory::AUTOCOMPLETE_IMAGE_ID)
public function getImageUrl($productId, $imageId = ItemFactory::AUTOCOMPLETE_IMAGE_ID): string
{
try {
$product = $this->getProductRepository()->getById($productId, false, $this->getStoreManager()->getStore()->getId());
} catch (\Magento\Framework\Exception\NoSuchEntityException $exception) {
return '';
$storeId = (int) $this->getStoreManager()->getStore()->getId();
$mediaData = $this->getMediaData($imageId, $storeId);
$imageType = $mediaData['image_type'] ?? 'thumbnail';
$productImage = $this->productResource->getAttributeRawValue($productId, $imageType, $storeId);
/** @var AssetImage $imageAsset */
$imageAsset = $this->assetImageFactory->create(
[
'miscParams' => $mediaData,
'filePath' => trim($productImage, '/'),
]
);
if ($productImage) {
return $imageAsset->getUrl();
}

$helper = $this->getImageHelper();
$helper->init($product, $imageId);

return $helper->getUrl();
return $this->getPlaceholder($imageType);
}

/**
* @return ProductRepositoryInterface
* Get media data from view configuration.
*
* @SuppressWarnings(PHPMD.ElseExpression)
*
* @param string $imageId Image id
* @param int $storeId Store id
*
* @return array
*/
private function getProductRepository()
protected function getMediaData($imageId, $storeId)
{
return $this->productRepositoryFactory->create();
$cacheKey = 'instant_search_media_data_thumbnail' . $storeId . '-' . $imageId;
$mediaData = $this->cache->load($cacheKey);
if ($mediaData === false) {
$currentTheme = $this->design->getDesignTheme();
$config = $this->viewConfig->getViewConfig(
[
'area' => Area::AREA_FRONTEND,
'themeModel' => $currentTheme,
]
);
$mediaAttributes = $config->getMediaAttributes('Magento_Catalog', Image::MEDIA_TYPE_CONFIG_NODE, $imageId);
$mediaData = $this->paramsBuilder->build($mediaAttributes, (int) $storeId);
$this->cache->save($this->serializer->serialize($mediaData), $cacheKey);

return $mediaData;
} else {
return $this->serializer->unserialize($mediaData);
}
}

/**
* @return StoreManagerInterface
*/
private function getStoreManager()
{
if (null === $this->storeManager) {
$this->storeManager = $this->storeManagerFactory->create();
}

return $this->storeManager;
return $this->storeManagerFactory->create();
}

/**
* @return ImageHelper
* Get placeholder.
*
* @param string $imageType Image type
*
* @return string
*/
private function getImageHelper()
private function getPlaceholder(string $imageType): string
{
return $this->imageHelperFactory->create();
$imageAsset = $this->placeholderFactory->create(['type' => $imageType]);

// Check if placeholder defined in config.
if ($imageAsset->getFilePath()) {
return $imageAsset->getUrl();
}

return $this->assetRepository->getUrl("Magento_Catalog::images/product/placeholder/{$imageType}.jpg");
}
}

0 comments on commit bd92d94

Please sign in to comment.