From 71de4cc80cc369fbaacaf906fd74747854013317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20B=C3=A9jean?= <nicolas@bejean.eu> Date: Fri, 8 May 2020 17:11:30 +0200 Subject: [PATCH] =?UTF-8?q?D=C3=A9veloppement=20des=20models?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CategoryWidgetStoreFilter.php | 34 +++ Model/CategoryWidget.php | 245 ++++++++++++++++ Model/CategoryWidget/DataProvider.php | 94 ++++++ Model/CategoryWidget/Source/Enabled.php | 52 ++++ Model/CategoryWidgetRepository.php | 206 ++++++++++++++ Model/Config/Source/CategoryWidget.php | 50 ++++ Model/GetCategoryWidgetByIdentifier.php | 59 ++++ Model/Resolver/CategoryWidget/Identity.php | 47 +++ Model/Resolver/CategoryWidgets.php | 96 +++++++ .../Resolver/DataProvider/CategoryWidget.php | 75 +++++ Model/ResourceModel/AbstractCollection.php | 222 +++++++++++++++ Model/ResourceModel/CategoryWidget.php | 269 ++++++++++++++++++ .../CategoryWidget/Collection.php | 103 +++++++ .../CategoryWidget/Grid/Collection.php | 158 ++++++++++ .../Relation/Store/ReadHandler.php | 53 ++++ .../Relation/Store/SaveHandler.php | 84 ++++++ Model/Template/Filter.php | 36 +++ Model/Template/FilterProvider.php | 74 +++++ 18 files changed, 1957 insertions(+) create mode 100755 Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryWidgetStoreFilter.php create mode 100755 Model/CategoryWidget.php create mode 100755 Model/CategoryWidget/DataProvider.php create mode 100755 Model/CategoryWidget/Source/Enabled.php create mode 100755 Model/CategoryWidgetRepository.php create mode 100755 Model/Config/Source/CategoryWidget.php create mode 100755 Model/GetCategoryWidgetByIdentifier.php create mode 100644 Model/Resolver/CategoryWidget/Identity.php create mode 100644 Model/Resolver/CategoryWidgets.php create mode 100644 Model/Resolver/DataProvider/CategoryWidget.php create mode 100755 Model/ResourceModel/AbstractCollection.php create mode 100755 Model/ResourceModel/CategoryWidget.php create mode 100755 Model/ResourceModel/CategoryWidget/Collection.php create mode 100755 Model/ResourceModel/CategoryWidget/Grid/Collection.php create mode 100755 Model/ResourceModel/CategoryWidget/Relation/Store/ReadHandler.php create mode 100755 Model/ResourceModel/CategoryWidget/Relation/Store/SaveHandler.php create mode 100755 Model/Template/Filter.php create mode 100755 Model/Template/FilterProvider.php diff --git a/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryWidgetStoreFilter.php b/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryWidgetStoreFilter.php new file mode 100755 index 0000000..8b4ce06 --- /dev/null +++ b/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryWidgetStoreFilter.php @@ -0,0 +1,34 @@ +<?php +namespace NicolasBejean\CategoryWidget\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use \Magento\Framework\Api\Filter; +use \Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; +use \Magento\Framework\Data\Collection\AbstractDb; +use \NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget\Collection; + +/** + * Class ImageStoreFilter + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class CategoryWidgetStoreFilter implements CustomFilterInterface +{ + /** + * Apply custom store filter to collection + * + * @param Filter $filter + * @param AbstractDb $collection + * @return bool + */ + public function apply(Filter $filter, AbstractDb $collection) + { + /** @var Collection $collection */ + $collection->addStoreFilter($filter->getValue(), false); + + return true; + } +} diff --git a/Model/CategoryWidget.php b/Model/CategoryWidget.php new file mode 100755 index 0000000..4a65b23 --- /dev/null +++ b/Model/CategoryWidget.php @@ -0,0 +1,245 @@ +<?php +namespace NicolasBejean\CategoryWidget\Model; + +use \Magento\Framework\Exception\LocalizedException; +use \NicolasBejean\CategoryWidget\Api\Data\CategoryWidgetInterface; +use \Magento\Framework\DataObject\IdentityInterface; +use \Magento\Framework\Model\AbstractModel; + +/** + * Class CategoryWidget + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class CategoryWidget extends AbstractModel implements CategoryWidgetInterface, IdentityInterface +{ + /** + * Category Widget Cache tag + * + * @var string + */ + const CACHE_TAG = 'categorywidget'; + + /** + * Category Widget statuses + */ + const STATUS_ENABLED = 1; + const STATUS_DISABLED = 0; + + /** + * Prefix of model events names + * + * @var string + */ + protected $eventPrefix = 'categorywidget'; + + /** + * @return void + */ + protected function _construct() + { + $this->_init(ResourceModel\CategoryWidget::class); + } + + /** + * Prevent category widgetrecursion + * + * @return AbstractModel + * @throws LocalizedException + */ + public function beforeSave() + { + if ($this->hasDataChanges()) { + $this->setUpdateTime(null); + } + + $needle = 'entity_id="' . $this->getId() . '"'; + if (false == strstr($this->getIdentifier(), $needle)) { + return parent::beforeSave(); + } + throw new LocalizedException( + __('Make sure that category widget path does not reference the category widget itself.') + ); + } + + /** + * Get identities + * + * @return array + */ + public function getIdentities() + { + return [self::CACHE_TAG . '_' . $this->getId(), self::CACHE_TAG . '_' . $this->getIdentifier()]; + } + + /** + * Retrieve category widgetid + * + * @return int + */ + public function getId() + { + return $this->getData(self::ENTITY_ID); + } + + /** + * Retrieve category widget identifier + * + * @return string + */ + public function getIdentifier() + { + return (string)$this->getData(self::IDENTIFIER); + } + + /** + * Retrieve category widget name + * + * @return string + */ + public function getName() + { + return $this->getData(self::NAME); + } + + /** + * Retrieve category widget content + * + * @return string + */ + public function getContent() + { + return $this->getData(self::CONTENT); + } + + /** + * Retrieve category widget creation time + * + * @return string + */ + public function getCreationTime() + { + return $this->getData(self::CREATION_TIME); + } + + /** + * Retrieve category widget update time + * + * @return string + */ + public function getUpdateTime() + { + return $this->getData(self::UPDATE_TIME); + } + + /** + * Is active + * + * @return bool + */ + public function isActive() + { + return (bool)$this->getData(self::IS_ACTIVE); + } + + /** + * Set ID + * + * @param int $id + * @return CategoryWidgetInterface + */ + public function setId($id) + { + return $this->setData(self::ENTITY_ID, $id); + } + + /** + * Set path + * + * @param string $identifier + * @return CategoryWidgetInterface + */ + public function setIdentifier($identifier) + { + return $this->setData(self::IDENTIFIER, $identifier); + } + + /** + * Set Name + * + * @param string $name + * @return CategoryWidgetInterface + */ + public function setName($name) + { + return $this->setData(self::NAME, $name); + } + + /** + * Set Content + * + * @param string $content + * @return CategoryWidgetInterface + */ + public function setContent($content) + { + return $this->setData(self::CONTENT, $content); + } + + /** + * Set creation time + * + * @param string $creationTime + * @return CategoryWidgetInterface + */ + public function setCreationTime($creationTime) + { + return $this->setData(self::CREATION_TIME, $creationTime); + } + + /** + * Set update time + * + * @param string $updateTime + * @return CategoryWidgetInterface + */ + public function setUpdateTime($updateTime) + { + return $this->setData(self::UPDATE_TIME, $updateTime); + } + + /** + * Set is active + * + * @param bool|int $isActive + * @return CategoryWidgetInterface + */ + public function setIsActive($isActive) + { + return $this->setData(self::IS_ACTIVE, $isActive); + } + + /** + * Receive slider store ids + * + * @return int[] + */ + public function getStores() + { + return $this->hasData('stores') ? $this->getData('stores') : $this->getData('store_id'); + } + + /** + * Prepare category widget statuses. + * + * @return array + */ + public function getAvailableStatuses() + { + return [self::STATUS_ENABLED => __('Enabled'), self::STATUS_DISABLED => __('Disabled')]; + } +} diff --git a/Model/CategoryWidget/DataProvider.php b/Model/CategoryWidget/DataProvider.php new file mode 100755 index 0000000..e9720c3 --- /dev/null +++ b/Model/CategoryWidget/DataProvider.php @@ -0,0 +1,94 @@ +<?php +namespace NicolasBejean\CategoryWidget\Model\CategoryWidget; + +use \NicolasBejean\CategoryWidget\Model\CategoryWidget; +use \NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget\Collection; +use \NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget\CollectionFactory; +use \Magento\Framework\App\Request\DataPersistorInterface; +use \Magento\Ui\DataProvider\AbstractDataProvider; + +/** + * Class DataProvider + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\CategoryWidget + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class DataProvider extends AbstractDataProvider +{ + /** + * @var Collection + */ + protected $collection; + + /** + * @var DataPersistorInterface + */ + protected $dataPersistor; + + /** + * @var array + */ + protected $loadedData; + + /** + * Constructor + * + * @param string $name + * @param string $primaryFieldName + * @param string $requestFieldName + * @param CollectionFactory $categoryWidgetCollectionFactory + * @param DataPersistorInterface $dataPersistor + * @param array $meta + * @param array $data + */ + public function __construct( + string $name, + string $primaryFieldName, + string $requestFieldName, + CollectionFactory $categoryWidgetCollectionFactory, + DataPersistorInterface $dataPersistor, + array $meta = [], + array $data = [] + ) { + $this->collection = $categoryWidgetCollectionFactory->create(); + $this->dataPersistor = $dataPersistor; + + parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data); + } + + /** + * Get data + * + * @return array + */ + public function getData() + { + if (isset($this->loadedData)) { + return $this->loadedData; + } + $items = $this->collection->getItems(); + /** @var CategoryWidget $categoryWidget */ + foreach ($items as $categoryWidget) { + $this->loadedData[$categoryWidget->getId()] = $categoryWidget->getData(); + if ($categoryWidget->getIdentifier()) { + $m['identifier'] = $categoryWidget->getIdentifier(); + $fullData = $this->loadedData; + $this->loadedData[$categoryWidget->getId()] = array_merge($fullData[$categoryWidget->getId()], $m); + } + } + + $data = $this->dataPersistor->get('nicolasbejean_categorywidget'); + + if (!empty($data)) { + $categoryWidget = $this->collection->getNewEmptyItem(); + $categoryWidget->setData($data); + $this->loadedData[$categoryWidget->getId()] = $categoryWidget->getData(); + $this->dataPersistor->clear('nicolasbejean_categorywidget'); + } + + return $this->loadedData; + } +} diff --git a/Model/CategoryWidget/Source/Enabled.php b/Model/CategoryWidget/Source/Enabled.php new file mode 100755 index 0000000..39e56fd --- /dev/null +++ b/Model/CategoryWidget/Source/Enabled.php @@ -0,0 +1,52 @@ +<?php +namespace NicolasBejean\CategoryWidget\Model\CategoryWidget\Source; + +use \Magento\Framework\Data\OptionSourceInterface; +use \NicolasBejean\CategoryWidget\Model\CategoryWidget; + +/** + * Class Enabled + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\CategoryWidget\Source + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class Enabled implements OptionSourceInterface +{ + /** + * @var CategoryWidget + */ + protected $categoryWidget; + + /** + * Constructor + * + * @param CategoryWidget $categoryWidget + */ + public function __construct( + CategoryWidget $categoryWidget + ) + { + $this->categoryWidget = $categoryWidget; + } + + /** + * Get options + * + * @return array + */ + public function toOptionArray() + { + $availableOptions = $this->categoryWidget->getAvailableStatuses(); + $options = []; + foreach ($availableOptions as $key => $value) { + $options[] = [ + 'label' => $value, + 'value' => $key, + ]; + } + return $options; + } +} diff --git a/Model/CategoryWidgetRepository.php b/Model/CategoryWidgetRepository.php new file mode 100755 index 0000000..bd9c657 --- /dev/null +++ b/Model/CategoryWidgetRepository.php @@ -0,0 +1,206 @@ +<?php +namespace NicolasBejean\CategoryWidget\Model; + +use \Magento\Framework\Api\SearchCriteriaInterface; +use \Magento\Framework\Exception\LocalizedException; +use \NicolasBejean\CategoryWidget\Api\Data\CategoryWidgetInterface; +use \NicolasBejean\CategoryWidget\Api\Data\CategoryWidgetInterfaceFactory; +use \NicolasBejean\CategoryWidget\Api\Data\CategoryWidgetSearchResultsInterface; +use \NicolasBejean\CategoryWidget\Api\CategoryWidgetRepositoryInterface; +use \NicolasBejean\CategoryWidget\Api\Data; +use \NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget as Resource; +use \NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget\Collection; +use \NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget\CollectionFactory as CategoryWidgetCollectionFactory; +use \Magento\Framework\Api\DataObjectHelper; +use \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; +use \Magento\Framework\Exception\CouldNotDeleteException; +use \Magento\Framework\Exception\CouldNotSaveException; +use \Magento\Framework\Exception\NoSuchEntityException; +use \Magento\Framework\Reflection\DataObjectProcessor; +use \Magento\Store\Model\StoreManagerInterface; +use \Exception; + +/** + * Class CategoryWidgetRepository + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class CategoryWidgetRepository implements CategoryWidgetRepositoryInterface +{ + /** + * @var Resource + */ + protected $resource; + + /** + * @var CategoryWidgetFactory + */ + protected $categoryWidgetFactory; + + /** + * @var CategoryWidgetCollectionFactory + */ + protected $categoryWidgetCollectionFactory; + + /** + * @var Data\CategoryWidgetSearchResultsInterfaceFactory + */ + protected $searchResultsFactory; + + /** + * @var DataObjectHelper + */ + protected $dataObjectHelper; + + /** + * @var DataObjectProcessor + */ + protected $dataObjectProcessor; + + /** + * @var CategoryWidgetInterfaceFactory + */ + protected $dataCategoryWidgetFactory; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var CollectionProcessorInterface + */ + private $collectionProcessor; + + /** + * @param Resource $resource + * @param CategoryWidgetFactory $categoryWidgetFactory + * @param CategoryWidgetInterfaceFactory $dataCategoryWidgetFactory + * @param CategoryWidgetCollectionFactory $categoryWidgetCollectionFactory + * @param Data\CategoryWidgetSearchResultsInterfaceFactory $searchResultsFactory + * @param DataObjectHelper $dataObjectHelper + * @param DataObjectProcessor $dataObjectProcessor + * @param StoreManagerInterface $storeManager + * @param CollectionProcessorInterface $collectionProcessor + */ + public function __construct( + Resource $resource, + CategoryWidgetFactory $categoryWidgetFactory, + CategoryWidgetInterfaceFactory $dataCategoryWidgetFactory, + CategoryWidgetCollectionFactory $categoryWidgetCollectionFactory, + Data\CategoryWidgetSearchResultsInterfaceFactory $searchResultsFactory, + DataObjectHelper $dataObjectHelper, + DataObjectProcessor $dataObjectProcessor, + StoreManagerInterface $storeManager, + CollectionProcessorInterface $collectionProcessor = null + ) { + $this->resource = $resource; + $this->categoryWidgetFactory = $categoryWidgetFactory; + $this->categoryWidgetCollectionFactory = $categoryWidgetCollectionFactory; + $this->searchResultsFactory = $searchResultsFactory; + $this->dataObjectHelper = $dataObjectHelper; + $this->dataCategoryWidgetFactory = $dataCategoryWidgetFactory; + $this->dataObjectProcessor = $dataObjectProcessor; + $this->storeManager = $storeManager; + $this->collectionProcessor = $collectionProcessor; + } + + /** + * Save Category Widget data + * + * @param CategoryWidgetInterface $categoryWidget + * @return CategoryWidgetInterface + * @throws CouldNotSaveException + * @throws NoSuchEntityException + */ + public function save(CategoryWidgetInterface $categoryWidget) + { + if (empty($categoryWidget->getStoreId())) { + $categoryWidget->setStoreId($this->storeManager->getStore()->getId()); + } + + try { + $this->resource->save($categoryWidget); + } catch (Exception $exception) { + throw new CouldNotSaveException(__($exception->getMessage())); + } + return $categoryWidget; + } + + /** + * Load Category Widget data by given Image Identity + * + * @param string $id + * @return CategoryWidget + * @throws NoSuchEntityException + * @throws LocalizedException + */ + public function getById($id) + { + /** @var CategoryWidget $categoryWidget */ + $categoryWidget = $this->categoryWidgetFactory->create(); + $this->resource->load($categoryWidget, $id); + if (!$categoryWidget->getId()) { + throw new NoSuchEntityException(__('The category widget with the \'%1\' ID doesn\'t exist.', $id)); + } + return $categoryWidget; + } + + /** + * Load Category Widget data collection by given search criteria + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + * @param SearchCriteriaInterface $criteria + * @return CategoryWidgetSearchResultsInterface + */ + public function getList(SearchCriteriaInterface $criteria) + { + /** @var Collection $collection */ + $collection = $this->categoryWidgetCollectionFactory->create(); + + $this->collectionProcessor->process($criteria, $collection); + + /** @var CategoryWidgetSearchResultsInterface $searchResults */ + $searchResults = $this->searchResultsFactory->create(); + $searchResults->setSearchCriteria($criteria); + $searchResults->setItems($collection->getItems()); + $searchResults->setTotalCount($collection->getSize()); + return $searchResults; + } + + /** + * Delete Category Widget + * + * @param CategoryWidgetInterface $categoryWidget + * @return bool + * @throws CouldNotDeleteException + */ + public function delete(CategoryWidgetInterface $categoryWidget) + { + try { + $this->resource->delete($categoryWidget); + } catch (Exception $exception) { + throw new CouldNotDeleteException(__($exception->getMessage())); + } + return true; + } + + /** + * Delete Category Widget by given Category Widget Identity + * + * @param string $id + * @return bool + * @throws CouldNotDeleteException + * @throws NoSuchEntityException + * @throws LocalizedException + */ + public function deleteById($id) + { + return $this->delete($this->getById($id)); + } +} diff --git a/Model/Config/Source/CategoryWidget.php b/Model/Config/Source/CategoryWidget.php new file mode 100755 index 0000000..eafc924 --- /dev/null +++ b/Model/Config/Source/CategoryWidget.php @@ -0,0 +1,50 @@ +<?php +declare(strict_types=1); + +namespace NicolasBejean\CategoryWidget\Model\Config\Source; + +use \NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget\CollectionFactory; +use \Magento\Framework\Data\OptionSourceInterface; + +/** + * Class CategoryWidget + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\Config\Source + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class CategoryWidget implements OptionSourceInterface +{ + /** + * @var array + */ + private $options; + + /** + * @var CollectionFactory + */ + private $collectionFactory; + + /** + * @param CollectionFactory $collectionFactory + */ + public function __construct( + CollectionFactory $collectionFactory + ) { + $this->collectionFactory = $collectionFactory; + } + + /** + * {@inheritdoc} + */ + public function toOptionArray() + { + if (!$this->options) { + $this->options = $this->collectionFactory->create()->toOptionIdArray(); + } + + return $this->options; + } +} diff --git a/Model/GetCategoryWidgetByIdentifier.php b/Model/GetCategoryWidgetByIdentifier.php new file mode 100755 index 0000000..aeeaba3 --- /dev/null +++ b/Model/GetCategoryWidgetByIdentifier.php @@ -0,0 +1,59 @@ +<?php +namespace NicolasBejean\CategoryWidget\Model; + +use \Magento\Framework\Exception\LocalizedException; +use \NicolasBejean\CategoryWidget\Api\GetCategoryWidgetByIdentifierInterface; +use \NicolasBejean\CategoryWidget\Api\Data\CategoryWidgetInterface; +use \Magento\Framework\Exception\NoSuchEntityException; +use \NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget as CategoryWidgetResource; + +/** + * Class GetCategoryWidgetByIdentifier + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class GetCategoryWidgetByIdentifier implements GetCategoryWidgetByIdentifierInterface +{ + /** + * @var CategoryWidgetFactory + */ + private $categoryWidgetFactory; + + /** + * @var CategoryWidgetResource + */ + private $categoryWidgetResource; + + /** + * @param CategoryWidgetFactory $categoryWidgetFactory + * @param CategoryWidgetResource $categoryWidgetResource + */ + public function __construct( + CategoryWidgetFactory $categoryWidgetFactory, + CategoryWidgetResource $categoryWidgetResource + ) { + $this->categoryWidgetFactory = $categoryWidgetFactory; + $this->categoryWidgetResource = $categoryWidgetResource; + } + + /** + * @inheritdoc + * @throws LocalizedException + */ + public function execute(string $identifier, int $storeId) : CategoryWidgetInterface + { + $categoryWidget = $this->categoryWidgetFactory->create(); + $categoryWidget->setStoreId($storeId); + $this->categoryWidgetResource->load($categoryWidget, $identifier, CategoryWidgetInterface::IDENTIFIER); + + if (!$categoryWidget->getId()) { + throw new NoSuchEntityException(__('The category widget with the \'%1\' identifier doesn\'t exist.', $identifier)); + } + + return $categoryWidget; + } +} diff --git a/Model/Resolver/CategoryWidget/Identity.php b/Model/Resolver/CategoryWidget/Identity.php new file mode 100644 index 0000000..8eb5b8d --- /dev/null +++ b/Model/Resolver/CategoryWidget/Identity.php @@ -0,0 +1,47 @@ +<?php +declare(strict_types=1); + +namespace NicolasBejean\CategoryWidget\Model\Resolver\CategoryWidget; + +use \NicolasBejean\CategoryWidget\Api\Data\CategoryWidgetInterface; + +use \Magento\Framework\GraphQl\Query\Resolver\IdentityInterface; + +/** + * Class CategoryWidget + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\Resolver\CategoryWidget + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class Identity implements IdentityInterface +{ + /** @var string */ + private $cacheTag = \NicolasBejean\CategoryWidget\Model\CategoryWidget::CACHE_TAG; + + /** + * Get Category Widget identities from resolved data + * + * @param array $resolvedData + * @return string[] + */ + public function getIdentities(array $resolvedData): array + { + $ids = []; + $items = $resolvedData['items'] ?? []; + foreach ($items as $item) { + if (is_array($item) && !empty($item[CategoryWidgetInterface::ENTITY_ID])) { + $ids[] = sprintf('%s_%s', $this->cacheTag, $item[CategoryWidgetInterface::ENTITY_ID]); + $ids[] = sprintf('%s_%s', $this->cacheTag, $item[CategoryWidgetInterface::IDENTIFIER]); + } + } + + if (!empty($ids)) { + array_unshift($ids, $this->cacheTag); + } + + return $ids; + } +} diff --git a/Model/Resolver/CategoryWidgets.php b/Model/Resolver/CategoryWidgets.php new file mode 100644 index 0000000..4985f60 --- /dev/null +++ b/Model/Resolver/CategoryWidgets.php @@ -0,0 +1,96 @@ +<?php +declare(strict_types=1); + +namespace NicolasBejean\CategoryWidget\Model\Resolver; + +use \NicolasBejean\CategoryWidget\Model\Resolver\DataProvider\CategoryWidget as CategoryWidgetDataProvider; + +use \Magento\Framework\GraphQl\Config\Element\Field; +use \Magento\Framework\GraphQl\Query\ResolverInterface; +use \Magento\Framework\GraphQl\Schema\Type\ResolveInfo; + +use \Magento\Framework\Exception\NoSuchEntityException; +use \Magento\Framework\GraphQl\Exception\GraphQlInputException; +use \Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; + +/** + * Class CategoryWidgets + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\Resolver + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class CategoryWidgets implements ResolverInterface +{ + /** + * @var CategoryWidgetDataProvider + */ + private $dataProvider; + + /** + * @param CategoryWidgetDataProvider $dataProvider + */ + public function __construct( + CategoryWidgetDataProvider $dataProvider + ) { + $this->dataProvider = $dataProvider; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + + $categoryWidgetIdentifiers = $this->getCategoryWidgetIdentifiers($args); + $categoryWidgetsData = $this->getCategoryWidgetsData($categoryWidgetIdentifiers); + + $resultData = [ + 'items' => $categoryWidgetsData, + ]; + return $resultData; + } + + /** + * Get Category Widget identifiers + * + * @param array $args + * @return string[] + * @throws GraphQlInputException + */ + private function getCategoryWidgetIdentifiers(array $args): array + { + if (!isset($args['identifiers']) || !is_array($args['identifiers']) || count($args['identifiers']) === 0) { + throw new GraphQlInputException(__('"identifiers" of Category Widgets should be specified')); + } + + return $args['identifiers']; + } + + /** + * Get category widgets data + * + * @param array $categoryWidgetIdentifiers + * @return array + * @throws GraphQlNoSuchEntityException + */ + private function getCategoryWidgetsData(array $categoryWidgetIdentifiers): array + { + $categoryWidgetsData = []; + foreach ($categoryWidgetIdentifiers as $categoryWidgetIdentifier) { + try { + $categoryWidgetsData[$categoryWidgetIdentifier] = $this->dataProvider->getData($categoryWidgetIdentifier); + } catch (NoSuchEntityException $e) { + $categoryWidgetsData[$categoryWidgetIdentifier] = new GraphQlNoSuchEntityException(__($e->getMessage()), $e); + } + } + return $categoryWidgetsData; + } +} diff --git a/Model/Resolver/DataProvider/CategoryWidget.php b/Model/Resolver/DataProvider/CategoryWidget.php new file mode 100644 index 0000000..f64fe34 --- /dev/null +++ b/Model/Resolver/DataProvider/CategoryWidget.php @@ -0,0 +1,75 @@ +<?php +declare(strict_types=1); + +namespace NicolasBejean\CategoryWidget\Model\Resolver\DataProvider; + +use \NicolasBejean\CategoryWidget\Api\CategoryWidgetRepositoryInterface; +use \NicolasBejean\CategoryWidget\Api\Data\CategoryWidgetInterface; +use \NicolasBejean\CategoryWidget\Model\CategoryWidget as CategoryWidgetModel; + +use \Magento\Widget\Model\Template\FilterEmulate; + +use \Magento\Framework\Exception\NoSuchEntityException; + +/** + * Class CategoryWidget + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\Resolver\DataProvider + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class CategoryWidget +{ + /** + * @var CategoryWidgetRepositoryInterface + */ + private $categoryWidgetRepository; + + /** + * @var FilterEmulate + */ + private $widgetFilter; + + /** + * @param CategoryWidgetRepositoryInterface $categoryWidgetRepository + * @param FilterEmulate $widgetFilter + */ + public function __construct( + CategoryWidgetRepositoryInterface $categoryWidgetRepository, + FilterEmulate $widgetFilter + ) { + $this->categoryWidgetRepository = $categoryWidgetRepository; + $this->widgetFilter = $widgetFilter; + } + + /** + * Get Category Widget data + * + * @param string $categoryWidgetIdentifier + * @return array + * @throws NoSuchEntityException + */ + public function getData(string $categoryWidgetIdentifier): array + { + /** @var CategoryWidgetModel $categoryWidget */ + $categoryWidget = $this->categoryWidgetRepository->getById($categoryWidgetIdentifier); + + if (false === $categoryWidget->isActive()) { + throw new NoSuchEntityException( + __('The Category Widget with the "%1" ID doesn\'t exist.', $categoryWidgetIdentifier) + ); + } + + /* TODO : Faire un explode du content pour renvoyer chaque category widget*/ + $content = $categoryWidget->getContent(); + + $categoryWidgetData = [ + CategoryWidgetInterface::IDENTIFIER => $categoryWidget->getIdentifier(), + CategoryWidgetInterface::NAME => $categoryWidget->getName(), + CategoryWidgetInterface::CONTENT => $content, + ]; + return $categoryWidgetData; + } +} diff --git a/Model/ResourceModel/AbstractCollection.php b/Model/ResourceModel/AbstractCollection.php new file mode 100755 index 0000000..eb950c5 --- /dev/null +++ b/Model/ResourceModel/AbstractCollection.php @@ -0,0 +1,222 @@ +<?php +namespace NicolasBejean\CategoryWidget\Model\ResourceModel; + +use \Magento\Framework\Data\Collection\Db\FetchStrategyInterface; +use \Magento\Framework\Data\Collection\EntityFactoryInterface; +use \Magento\Framework\DB\Adapter\AdapterInterface; +use \Magento\Framework\DB\Select; +use \Magento\Framework\EntityManager\MetadataPool; +use \Magento\Framework\Event\ManagerInterface; +use \Magento\Framework\Exception\NoSuchEntityException; +use \Magento\Framework\Model\ResourceModel\Db\AbstractDb; +use \Magento\Store\Model\Store; +use \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection as AbstractCollectionExtends; +use \Magento\Store\Model\StoreManagerInterface; +use \Psr\Log\LoggerInterface; + +/** + * Class AbstractCollection + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\ResourceModel + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +abstract class AbstractCollection extends AbstractCollectionExtends +{ + /** + * Store manager + * + * @var StoreManagerInterface + */ + protected $storeManager; + + /** + * @var MetadataPool + */ + protected $metadataPool; + + /** + * @param EntityFactoryInterface $entityFactory + * @param LoggerInterface $logger + * @param FetchStrategyInterface $fetchStrategy + * @param ManagerInterface $eventManager + * @param StoreManagerInterface $storeManager + * @param MetadataPool $metadataPool + * @param AdapterInterface|null $connection + * @param AbstractDb|null $resource + */ + public function __construct( + EntityFactoryInterface $entityFactory, + LoggerInterface $logger, + FetchStrategyInterface $fetchStrategy, + ManagerInterface $eventManager, + StoreManagerInterface $storeManager, + MetadataPool $metadataPool, + AdapterInterface $connection = null, + AbstractDb $resource = null + ) { + $this->storeManager = $storeManager; + $this->metadataPool = $metadataPool; + + parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource); + } + + /** + * Perform operations after collection load + * + * @param string $tableName + * @param string|null $linkField + * @return void + * @throws NoSuchEntityException + */ + protected function performAfterLoad($tableName, $linkField) + { + $linkedIds = $this->getColumnValues($linkField); + if (count($linkedIds)) { + $connection = $this->getConnection(); + $select = $connection->select()->from(['cms_entity_store' => $this->getTable($tableName)]) + ->where('cms_entity_store.' . $linkField . ' IN (?)', $linkedIds); + $result = $connection->fetchAll($select); + if ($result) { + $storesData = []; + foreach ($result as $storeData) { + $storesData[$storeData[$linkField]][] = $storeData['store_id']; + } + + foreach ($this as $item) { + $linkedId = $item->getData($linkField); + if (!isset($storesData[$linkedId])) { + continue; + } + $storeIdKey = array_search(Store::DEFAULT_STORE_ID, $storesData[$linkedId], true); + if ($storeIdKey !== false) { + $stores = $this->storeManager->getStores(false, true); + $storeId = current($stores)->getId(); + $storeCode = key($stores); + } else { + $storeId = current($storesData[$linkedId]); + $storeCode = $this->storeManager->getStore($storeId)->getCode(); + } + $item->setData('_first_store_id', $storeId); + $item->setData('store_code', $storeCode); + $item->setData('store_id', $storesData[$linkedId]); + } + } + } + } + + /** + * Add field filter to collection + * + * @param array|string $field + * @param string|int|array|null $condition + * @return AbstractCollectionExtends + */ + public function addFieldToFilter($field, $condition = null) + { + if ($field === 'store_id') { + return $this->addStoreFilter($condition, false); + } + + return parent::addFieldToFilter($field, $condition); + } + + /** + * Add filter by store + * + * @param int|array|Store $store + * @param bool $withAdmin + * @return $this + */ + abstract public function addStoreFilter($store, $withAdmin = true); + + /** + * Perform adding filter by store + * + * @param int|array|Store $store + * @param bool $withAdmin + * @return void + */ + protected function performAddStoreFilter($store, $withAdmin = true) + { + if ($store instanceof Store) { + $store = [$store->getId()]; + } + + if (!is_array($store)) { + $store = [$store]; + } + + if ($withAdmin) { + $store[] = Store::DEFAULT_STORE_ID; + } + + $this->addFilter('store', ['in' => $store], 'public'); + } + + /** + * Join store relation table if there is store filter + * + * @param string $tableName + * @param string|null $linkField + * @return void + */ + protected function joinStoreRelationTable($tableName, $linkField) + { + if ($this->getFilter('store')) { + $this->getSelect()->join( + ['store_table' => $this->getTable($tableName)], + 'main_table.' . $linkField . ' = store_table.' . $linkField, + [] + )->group( + 'main_table.' . $linkField + ); + } + parent::_renderFiltersBefore(); + } + + /** + * Get SQL for get record count + * + * Extra GROUP BY strip added. + * + * @return Select + */ + public function getSelectCountSql() + { + $countSelect = parent::getSelectCountSql(); + $countSelect->reset(Select::GROUP); + + return $countSelect; + } + + /** + * Returns pairs identifier - title for unique identifiers + * and pairs identifier|entity_id - title for non-unique after first + * + * @return array + */ + public function toOptionIdArray() + { + $res = []; + $existingIdentifiers = []; + foreach ($this as $item) { + $identifier = $item->getData('identifier'); + + $data['value'] = $identifier; + $data['label'] = $item->getData('title'); + + if (in_array($identifier, $existingIdentifiers)) { + $data['value'] .= '|' . $item->getData($this->getIdFieldName()); + } else { + $existingIdentifiers[] = $identifier; + } + + $res[] = $data; + } + + return $res; + } +} diff --git a/Model/ResourceModel/CategoryWidget.php b/Model/ResourceModel/CategoryWidget.php new file mode 100755 index 0000000..3ef608c --- /dev/null +++ b/Model/ResourceModel/CategoryWidget.php @@ -0,0 +1,269 @@ +<?php +namespace NicolasBejean\CategoryWidget\Model\ResourceModel; + +use \NicolasBejean\CategoryWidget\Api\Data\CategoryWidgetInterface; +use \Magento\Framework\DB\Select; +use \Magento\Framework\EntityManager\EntityManager; +use \Magento\Framework\EntityManager\MetadataPool; +use \Magento\Framework\Exception\LocalizedException; +use \Magento\Framework\Model\AbstractModel; +use \Magento\Framework\Model\ResourceModel\Db\AbstractDb; +use \Magento\Framework\Model\ResourceModel\Db\Context; +use \Magento\Store\Model\Store; +use \Magento\Store\Model\StoreManagerInterface; +use \Exception; +use \NicolasBejean\CategoryWidget\Model\CategoryWidget as CategoryWidgetModel; + +/** + * Class CategoryWidget + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\ResourceModel + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class CategoryWidget extends AbstractDb +{ + /** + * Store manager + * + * @var StoreManagerInterface + */ + protected $storeManager; + + /** + * @var EntityManager + */ + protected $entityManager; + + /** + * @var MetadataPool + */ + protected $metadataPool; + + /** + * @param Context $context + * @param StoreManagerInterface $storeManager + * @param EntityManager $entityManager + * @param MetadataPool $metadataPool + * @param string $connectionName + */ + public function __construct( + Context $context, + StoreManagerInterface $storeManager, + EntityManager $entityManager, + MetadataPool $metadataPool, + $connectionName = null + ) { + $this->storeManager = $storeManager; + $this->entityManager = $entityManager; + $this->metadataPool = $metadataPool; + + parent::__construct($context, $connectionName); + } + + /** + * Initialize resource model + * + * @return void + */ + protected function _construct() + { + $this->_init('nicolasbejean_categorywidget', 'entity_id'); + } + + /** + * @inheritDoc + * @throws Exception + */ + public function getConnection() + { + return $this->metadataPool->getMetadata(CategoryWidgetInterface::class)->getEntityConnection(); + } + + /** + * Perform operations before object save + * + * @param AbstractModel $object + * @return $this + * @throws LocalizedException + */ + protected function _beforeSave(AbstractModel $object) + { + if (!$this->getIsUniqueCategoryWidgetToStores($object)) { + throw new LocalizedException( + __('A category widget identifier with the same properties already exists in the selected store.') + ); + } + return $this; + } + + /** + * @param AbstractModel $object + * @param mixed $value + * @param null $field + * @return bool|int|string + * @throws LocalizedException + * @throws Exception + */ + private function getCategoryWidgetId(AbstractModel $object, $value, $field = null) + { + $entityMetadata = $this->metadataPool->getMetadata(CategoryWidgetInterface::class); + if (!is_numeric($value) && $field === null) { + $field = 'identifier'; + } elseif (!$field) { + $field = $entityMetadata->getIdentifierField(); + } + $entityId = $value; + if ($field != $entityMetadata->getIdentifierField() || $object->getStoreId()) { + $select = $this->_getLoadSelect($field, $value, $object); + $select->reset(Select::COLUMNS) + ->columns($this->getMainTable() . '.' . $entityMetadata->getIdentifierField()) + ->limit(1); + $result = $this->getConnection()->fetchCol($select); + $entityId = count($result) ? $result[0] : false; + } + return $entityId; + } + + /** + * Load an object + * + * @param CategoryWidgetModel|AbstractModel $object + * @param mixed $value + * @param string $field field to load by (defaults to model id) + * @return $this + * @throws LocalizedException + */ + public function load(AbstractModel $object, $value, $field = null) + { + $categoryWidgetId = $this->getCategoryWidgetId($object, $value, $field); + if ($categoryWidgetId) { + $this->entityManager->load($object, $categoryWidgetId); + } + return $this; + } + + /** + * Retrieve select object for load object data + * + * @param string $field + * @param mixed $value + * @param CategoryWidgetModel|AbstractModel $object + * @return Select + * @throws LocalizedException + * @throws Exception + */ + protected function _getLoadSelect($field, $value, $object) + { + $entityMetadata = $this->metadataPool->getMetadata(CategoryWidgetInterface::class); + $linkField = $entityMetadata->getLinkField(); + + $select = parent::_getLoadSelect($field, $value, $object); + + if ($object->getStoreId()) { + $stores = [(int)$object->getStoreId(), Store::DEFAULT_STORE_ID]; + + $select->join( + ['niis' => $this->getTable('nicolasbejean_categorywidget_store')], + $this->getMainTable() . '.' . $linkField . ' = niis.' . $linkField, + ['store_id'] + ) + ->where('is_active = ?', 1) + ->where('niis.store_id in (?)', $stores) + ->order('store_id DESC') + ->limit(1); + } + + return $select; + } + + /** + * Check for unique of path of category widgetto selected store(s). + * + * @param AbstractModel $object + * @return bool + * @SuppressWarnings(PHPMD.BooleanGetMethodName) + * @throws LocalizedException + * @throws Exception + */ + public function getIsUniqueCategoryWidgetToStores(AbstractModel $object) + { + $entityMetadata = $this->metadataPool->getMetadata(CategoryWidgetInterface::class); + $linkField = $entityMetadata->getLinkField(); + + if ($this->storeManager->isSingleStoreMode()) { + $stores = [Store::DEFAULT_STORE_ID]; + } else { + $stores = (array)$object->getData('store_id'); + } + + $select = $this->getConnection()->select() + ->from(['nii' => $this->getMainTable()]) + ->join( + ['niis' => $this->getTable('nicolasbejean_categorywidget_store')], + 'nii.' . $linkField . ' = niis.' . $linkField, + [] + ) + ->where('nii.identifier = ?', $object->getData('identifier')) + ->where('niis.store_id IN (?)', $stores); + + if ($object->getId()) { + $select->where('nii.' . $entityMetadata->getIdentifierField() . ' <> ?', $object->getId()); + } + + if ($this->getConnection()->fetchRow($select)) { + return false; + } + + return true; + } + + /** + * Get store ids to which specified item is assigned + * + * @param int $id + * @return array + * @throws LocalizedException + * @throws Exception + */ + public function lookupStoreIds($id) + { + $connection = $this->getConnection(); + + $entityMetadata = $this->metadataPool->getMetadata(CategoryWidgetInterface::class); + $linkField = $entityMetadata->getLinkField(); + + $select = $connection->select() + ->from(['niis' => $this->getTable('nicolasbejean_categorywidget_store')], 'store_id') + ->join( + ['nii' => $this->getMainTable()], + 'niis.' . $linkField . ' = nii.' . $linkField, + [] + ) + ->where('nii.' . $entityMetadata->getIdentifierField() . ' = :entity_id'); + + return $connection->fetchCol($select, ['entity_id' => (int)$id]); + } + + /** + * @param AbstractModel $object + * @return $this + * @throws Exception + */ + public function save(AbstractModel $object) + { + $this->entityManager->save($object); + return $this; + } + + /** + * @inheritDoc + */ + public function delete(AbstractModel $object) + { + $this->entityManager->delete($object); + return $this; + } +} diff --git a/Model/ResourceModel/CategoryWidget/Collection.php b/Model/ResourceModel/CategoryWidget/Collection.php new file mode 100755 index 0000000..4d12d7f --- /dev/null +++ b/Model/ResourceModel/CategoryWidget/Collection.php @@ -0,0 +1,103 @@ +<?php +namespace NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget; + +use \Magento\Store\Model\Store; +use \NicolasBejean\CategoryWidget\Api\Data\CategoryWidgetInterface; +use \NicolasBejean\CategoryWidget\Model\CategoryWidget as CategoryWidgetModel; +use \NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget as CategoryWidgetResourceModel; +use \NicolasBejean\CategoryWidget\Model\ResourceModel\AbstractCollection; +use \Exception; + +/** + * Class Collection + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class Collection extends AbstractCollection +{ + /** + * @var string + */ + protected $_idFieldName = 'entity_id'; + + /** + * Event prefix + * + * @var string + */ + protected $eventPrefix = 'categorywidget_collection'; + + /** + * Event object + * + * @var string + */ + protected $eventObject = 'categorywidget_collection'; + + /** + * Perform operations after collection load + * + * @return AbstractCollection + * @throws Exception + */ + protected function _afterLoad() + { + $entityMetadata = $this->metadataPool->getMetadata(CategoryWidgetInterface::class); + + $this->performAfterLoad('nicolasbejean_categorywidget_store', $entityMetadata->getLinkField()); + + return parent::_afterLoad(); + } + + /** + * Define resource model + * + * @return void + */ + protected function _construct() + { + $this->_init(CategoryWidgetModel::class, CategoryWidgetResourceModel::class); + $this->_map['fields']['store'] = 'store_table.store_id'; + $this->_map['fields']['entity_id'] = 'main_table.entity_id'; + } + + /** + * Returns pairs entity_id - identifier + * + * @return array + */ + public function toOptionArray() + { + return $this->_toOptionArray('entity_id', 'identifier'); + } + + /** + * Add filter by store + * + * @param int|array|Store $store + * @param bool $withAdmin + * @return $this + */ + public function addStoreFilter($store, $withAdmin = true) + { + $this->performAddStoreFilter($store, $withAdmin); + + return $this; + } + + /** + * Join store relation table if there is store filter + * + * @return void + * @throws Exception + */ + protected function _renderFiltersBefore() + { + $entityMetadata = $this->metadataPool->getMetadata(CategoryWidgetInterface::class); + $this->joinStoreRelationTable('nicolasbejean_categorywidget_store', $entityMetadata->getLinkField()); + } +} diff --git a/Model/ResourceModel/CategoryWidget/Grid/Collection.php b/Model/ResourceModel/CategoryWidget/Grid/Collection.php new file mode 100755 index 0000000..290ec83 --- /dev/null +++ b/Model/ResourceModel/CategoryWidget/Grid/Collection.php @@ -0,0 +1,158 @@ +<?php +namespace NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget\Grid; + +use \Magento\Framework\Api\ExtensibleDataInterface; +use \Magento\Framework\Api\Search\SearchResultInterface; +use \Magento\Framework\Api\Search\AggregationInterface; +use \Magento\Framework\Api\SearchCriteriaInterface; +use \Magento\Framework\Data\Collection\Db\FetchStrategyInterface; +use \Magento\Framework\Data\Collection\EntityFactoryInterface; +use \Magento\Framework\DB\Adapter\AdapterInterface; +use \Magento\Framework\EntityManager\MetadataPool; +use \Magento\Framework\Event\ManagerInterface; +use \Magento\Framework\Model\ResourceModel\Db\AbstractDb; +use \Magento\Framework\View\Element\UiComponent\DataProvider\Document; +use \Magento\Store\Model\StoreManagerInterface; +use \NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget\Collection as CategoryWidgetCollection; +use \Psr\Log\LoggerInterface; + +/** + * Class Collection + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget\Grid + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class Collection extends CategoryWidgetCollection implements SearchResultInterface +{ + /** + * @var AggregationInterface + */ + protected $aggregations; + + /** + * @param EntityFactoryInterface $entityFactory + * @param LoggerInterface $logger + * @param FetchStrategyInterface $fetchStrategy + * @param ManagerInterface $eventManager + * @param StoreManagerInterface $storeManager + * @param MetadataPool $metadataPool + * @param string $mainTable + * @param string $eventPrefix + * @param string $eventObject + * @param string $resourceModel + * @param string $model + * @param AdapterInterface $connection + * @param AbstractDb $resource + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ + public function __construct( + EntityFactoryInterface $entityFactory, + LoggerInterface $logger, + FetchStrategyInterface $fetchStrategy, + ManagerInterface $eventManager, + StoreManagerInterface $storeManager, + MetadataPool $metadataPool, + string $mainTable, + string $eventPrefix, + string $eventObject, + string $resourceModel, + string $model = Document::class, + AdapterInterface $connection = null, + AbstractDb $resource = null + ) { + $this->_eventPrefix = $eventPrefix; + $this->_eventObject = $eventObject; + + parent::__construct( + $entityFactory, + $logger, + $fetchStrategy, + $eventManager, + $storeManager, + $metadataPool, + $connection, + $resource + ); + + $this->_init($model, $resourceModel); + $this->setMainTable($mainTable); + } + + /** + * @return AggregationInterface + */ + public function getAggregations() + { + return $this->aggregations; + } + + /** + * @param AggregationInterface $aggregations + * @return $this + */ + public function setAggregations($aggregations) + { + $this->aggregations = $aggregations; + return $this; + } + + /** + * Get search criteria. + * + * @return SearchCriteriaInterface|null + */ + public function getSearchCriteria() + { + return null; + } + + /** + * Set search criteria. + * + * @param SearchCriteriaInterface $searchCriteria + * @return $this + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function setSearchCriteria(SearchCriteriaInterface $searchCriteria = null) + { + return $this; + } + + /** + * Get total count. + * + * @return int + */ + public function getTotalCount() + { + return $this->getSize(); + } + + /** + * Set total count. + * + * @param int $totalCount + * @return $this + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function setTotalCount($totalCount) + { + return $this; + } + + /** + * Set items list. + * + * @param ExtensibleDataInterface[] $items + * @return $this + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function setItems(array $items = null) + { + return $this; + } +} diff --git a/Model/ResourceModel/CategoryWidget/Relation/Store/ReadHandler.php b/Model/ResourceModel/CategoryWidget/Relation/Store/ReadHandler.php new file mode 100755 index 0000000..d2ced62 --- /dev/null +++ b/Model/ResourceModel/CategoryWidget/Relation/Store/ReadHandler.php @@ -0,0 +1,53 @@ +<?php +namespace NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget\Relation\Store; + +use \Magento\Framework\Exception\LocalizedException; +use \NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget; +use \Magento\Framework\EntityManager\Operation\ExtensionInterface; +use \Exception; + +/** + * Class ReadHandler + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget\Relation\Store + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class ReadHandler implements ExtensionInterface +{ + /** + * @var CategoryWidget + */ + protected $resourceCategoryWidget; + + /** + * @param CategoryWidget $resourceCategoryWidget + */ + public function __construct( + CategoryWidget $resourceCategoryWidget + ) { + $this->resourceCategoryWidget = $resourceCategoryWidget; + } + + /** + * @param object $entity + * @param array $arguments + * @return object + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @throws Exception + */ + public function execute($entity, $arguments = []) + { + if ($entity->getId()) { + try { + $stores = $this->resourceCategoryWidget->lookupStoreIds((int)$entity->getId()); + } catch (Exception $e) { + } + $entity->setData('store_id', $stores); + $entity->setData('stores', $stores); + } + return $entity; + } +} diff --git a/Model/ResourceModel/CategoryWidget/Relation/Store/SaveHandler.php b/Model/ResourceModel/CategoryWidget/Relation/Store/SaveHandler.php new file mode 100755 index 0000000..c3021b6 --- /dev/null +++ b/Model/ResourceModel/CategoryWidget/Relation/Store/SaveHandler.php @@ -0,0 +1,84 @@ +<?php +namespace NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget\Relation\Store; + +use \Magento\Framework\EntityManager\Operation\ExtensionInterface; +use \NicolasBejean\CategoryWidget\Api\Data\CategoryWidgetInterface; +use \NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget; +use \Magento\Framework\EntityManager\MetadataPool; +use \Exception; + +/** + * Class SaveHandler + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\ResourceModel\CategoryWidget\Relation\Store + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class SaveHandler implements ExtensionInterface +{ + /** + * @var MetadataPool + */ + protected $metadataPool; + + /** + * @var CategoryWidget + */ + protected $resourceCategoryWidget; + + /** + * @param MetadataPool $metadataPool + * @param CategoryWidget $resourceCategoryWidget + */ + public function __construct( + MetadataPool $metadataPool, + CategoryWidget $resourceCategoryWidget + ) { + $this->metadataPool = $metadataPool; + $this->resourceCategoryWidget = $resourceCategoryWidget; + } + + /** + * @param object $entity + * @param array $arguments + * @return object + * @throws Exception + */ + public function execute($entity, $arguments = []) + { + $entityMetadata = $this->metadataPool->getMetadata(CategoryWidgetInterface::class); + $linkField = $entityMetadata->getLinkField(); + + $connection = $entityMetadata->getEntityConnection(); + + $oldStores = $this->resourceCategoryWidget->lookupStoreIds((int)$entity->getId()); + $newStores = (array)$entity->getStores(); + + $table = $this->resourceCategoryWidget->getTable('nicolasbejean_categorywidget_store'); + + $delete = array_diff($oldStores, $newStores); + if ($delete) { + $where = [ + $linkField . ' = ?' => (int)$entity->getData($linkField), + 'store_id IN (?)' => $delete, + ]; + $connection->delete($table, $where); + } + + $insert = array_diff($newStores, $oldStores); + if ($insert) { + $data = []; + foreach ($insert as $storeId) { + $data[] = [ + $linkField => (int)$entity->getData($linkField), + 'store_id' => (int)$storeId, + ]; + } + $connection->insertMultiple($table, $data); + } + + return $entity; + } +} diff --git a/Model/Template/Filter.php b/Model/Template/Filter.php new file mode 100755 index 0000000..29b889c --- /dev/null +++ b/Model/Template/Filter.php @@ -0,0 +1,36 @@ +<?php +namespace NicolasBejean\CategoryWidget\Model\Template; + +use \Magento\Email\Model\Template\Filter as FilterExtends; +use \Magento\Framework\Exception\NoSuchEntityException; + +/** + * Class Filter + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\Template + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class Filter extends FilterExtends +{ + /** + * Whether to allow SID in store directive: AUTO + * + * @var bool + */ + protected $useSessionInUrl; + + /** + * Setter whether SID is allowed in store directive + * + * @param bool $flag + * @return $this + */ + public function setUseSessionInUrl($flag) + { + $this->_useSessionInUrl = (bool)$flag; + return $this; + } +} diff --git a/Model/Template/FilterProvider.php b/Model/Template/FilterProvider.php new file mode 100755 index 0000000..932fb31 --- /dev/null +++ b/Model/Template/FilterProvider.php @@ -0,0 +1,74 @@ +<?php +namespace NicolasBejean\CategoryWidget\Model\Template; + +use \Magento\Framework\Filter\Template; +use \Magento\Framework\ObjectManagerInterface; +use \Exception; + +/** + * Class FilterProvider + * + * @category PHP + * @package NicolasBejean\CategoryWidget\Model\Template + * @author Nicolas Béjean <nicolas@bejean.eu> + * @license https://github.com/nicolasbejean/category-widget/blob/master/licence.txt BSD Licence + * @link https://www.bejean.eu + */ +class FilterProvider +{ + /** + * @var ObjectManagerInterface + */ + protected $objectManager; + + /** + * @var string + */ + /** TODO : A Delete ? */ + protected $categoryWidgetFilter; + + /** + * @var array + */ + protected $instanceList; + + /** + * @param ObjectManagerInterface $objectManager + * @param string $categoryWidgetFilter + */ + public function __construct( + ObjectManagerInterface $objectManager, + $categoryWidgetFilter = Filter::class + ) { + $this->objectManager = $objectManager; + $this->categoryWidgetFilter = $categoryWidgetFilter; + } + + /** + * @param string $instanceName + * @return Template + * @throws Exception + */ + protected function _getFilterInstance($instanceName) + { + if (!isset($this->instanceList[$instanceName])) { + $instance = $this->objectManager->get($instanceName); + + if (!$instance instanceof Template) { + throw new Exception('Template filter ' . $instanceName . ' does not implement required interface'); + } + $this->instanceList[$instanceName] = $instance; + } + + return $this->instanceList[$instanceName]; + } + + /** + * @return Template + * @throws Exception + */ + public function getCategoryWidgetFilter() + { + return $this->_getFilterInstance($this->categoryWidgetFilter); + } +} -- GitLab