src/module-elasticsuite-virtual-category/Plugin/Catalog/Category/DataProviderPlugin.php
<?php
/**
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Smile ElasticSuite to newer
* versions in the future.
*
* @category Smile
* @package Smile\ElasticsuiteVirtualCategory
* @author Aurelien FOUCRET <aurelien.foucret@smile.fr>
* @copyright 2020 Smile
* @license Open Software License ("OSL") v. 3.0
*/
namespace Smile\ElasticsuiteVirtualCategory\Plugin\Catalog\Category;
use Magento\Catalog\Model\Category\DataProvider as CategoryDataProvider;
use Magento\Store\Model\StoreManagerInterface;
use \Smile\ElasticsuiteVirtualCategory\Model\ResourceModel\Category\Product\Position as ProductPositionResource;
use Magento\Catalog\Model\Category;
/**
* Extenstion of the category form UI data provider.
*
* @category Smile
* @package Smile\ElasticsuiteVirtualCategory
* @author Aurelien FOUCRET <aurelien.foucret@smile.fr>
*/
class DataProviderPlugin
{
/**
*
* @var \Smile\ElasticsuiteVirtualCategory\Model\ResourceModel\Category\Product\Position
*/
private $productPositionResource;
/**
* @var \Magento\Backend\Model\UrlInterface
*/
private $urlBuilder;
/**
* @var \Magento\Framework\Locale\FormatInterface
*/
private $localeFormat;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
private $storeManager;
/**
* Constructor.
*
* @param ProductPositionResource $productPositionResource Product position resource model.
* @param \Magento\Framework\Locale\FormatInterface $localeFormat Locale formater.
* @param \Magento\Backend\Model\UrlInterface $urlBuilder Admin URL Builder.
* @param StoreManagerInterface $storeManagerInterface Store Manager.
*/
public function __construct(
ProductPositionResource $productPositionResource,
\Magento\Framework\Locale\FormatInterface $localeFormat,
\Magento\Backend\Model\UrlInterface $urlBuilder,
StoreManagerInterface $storeManagerInterface
) {
$this->productPositionResource = $productPositionResource;
$this->localeFormat = $localeFormat;
$this->urlBuilder = $urlBuilder;
$this->storeManager = $storeManagerInterface;
}
/**
* Append virtual rule and sorting product data.
*
* @param CategoryDataProvider $dataProvider Data provider.
* @param \Closure $proceed Original method.
*
* @return array
*/
public function aroundGetData(CategoryDataProvider $dataProvider, \Closure $proceed)
{
$data = $proceed();
$currentCategory = $dataProvider->getCurrentCategory();
if ($currentCategory->getId() === null || $currentCategory->getLevel() < 2) {
$data[$currentCategory->getId()]['use_default']['is_virtual_category'] = true;
}
if ($currentCategory->getLevel() >= 2 && !isset($data[$currentCategory->getId()]['virtual_category_root'])) {
$data[$currentCategory->getId()]['virtual_category_root'] = $currentCategory->getPathIds()[1];
}
$data[$currentCategory->getId()]['use_default']['show_use_store_positions'] = true;
if (!$currentCategory->getStoreId() || $currentCategory->getId() === null) {
$data[$currentCategory->getId()]['use_default']['show_use_store_positions'] = false;
}
// To restore global/"All store views" positions/blacklist.
$data[$currentCategory->getId()]['default']['sorted_products'] = [];
$data[$currentCategory->getId()]['default']['blacklisted_products'] = [];
if ($currentCategory->getStoreId()) {
$globalCategory = clone $currentCategory;
$globalCategory->setUseStorePositions(false);
$data[$currentCategory->getId()]['default']['sorted_products'] = $this->getProductSavedPositions($globalCategory);
$data[$currentCategory->getId()]['default']['blacklisted_products'] = $this->getBlacklistedProducts($globalCategory);
}
$data[$currentCategory->getId()]['sorted_products'] = $this->getProductSavedPositions($currentCategory);
$data[$currentCategory->getId()]['blacklisted_products'] = $this->getBlacklistedProducts($currentCategory);
$data[$currentCategory->getId()]['product_sorter_load_url'] = $this->getProductSorterLoadUrl($currentCategory);
$data[$currentCategory->getId()]['price_format'] = $this->localeFormat->getPriceFormat();
return $data;
}
/**
* Retrieve the category product sorter load URL.
*
* @param Category $category Category.
*
* @return string|null
*/
private function getProductSorterLoadUrl(Category $category)
{
$url = null;
$storeId = $this->getStoreId($category);
if ($storeId) {
$urlParams = ['ajax' => true, 'store' => $storeId];
$url = $this->urlBuilder->getUrl('virtualcategory/category_virtual/preview', $urlParams);
}
return $url;
}
/**
* Load product saved positions for the current category.
*
* @param Category $category Category.
*
* @return array
*/
private function getProductSavedPositions(Category $category)
{
$productPositions = [];
if ($category->getId()) {
$productPositions = $this->productPositionResource->getProductPositionsByCategory($category);
}
return json_encode($productPositions, JSON_FORCE_OBJECT);
}
/**
* Return list of blacklisted products for the current category.
*
* @param Category $category Category.
*
* @return array
*/
private function getBlacklistedProducts(Category $category)
{
$productIds = $this->productPositionResource->getProductBlacklistByCategory($category);
return array_map('intval', $productIds);
}
/**
* Retrieve default store view id.
*
* @return int
*/
private function getDefaultStoreId()
{
$store = $this->storeManager->getDefaultStoreView();
if (null === $store) {
// Occurs when current user does not have access to default website (due to AdminGWS ACLS on Magento EE).
$store = !empty($this->storeManager->getWebsites()) ? current($this->storeManager->getWebsites())->getDefaultStore() : null;
}
return $store ? $store->getId() : 0;
}
/**
* Get store id for the current category.
*
*
* @param Category $category Category.
*
* @return int
*/
private function getStoreId(Category $category)
{
$storeId = $category->getStoreId();
if ($storeId === 0) {
$defaultStoreId = $this->getDefaultStoreId();
$categoryStoreIds = array_filter($category->getStoreIds());
$storeId = current($categoryStoreIds);
if (in_array($defaultStoreId, $categoryStoreIds)) {
$storeId = $defaultStoreId;
}
}
return $storeId;
}
}