<?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( ['ncws' => $this->getTable('nicolasbejean_categorywidget_store')], $this->getMainTable() . '.' . $linkField . ' = ncws.' . $linkField, ['store_id'] ) ->where('is_active = ?', 1) ->where('ncws.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(['ncw' => $this->getMainTable()]) ->join( ['ncws' => $this->getTable('nicolasbejean_categorywidget_store')], 'ncw.' . $linkField . ' = ncws.' . $linkField, [] ) ->where('ncw.identifier = ?', $object->getData('identifier')) ->where('ncws.store_id IN (?)', $stores); if ($object->getId()) { $select->where('ncw.' . $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(['ncws' => $this->getTable('nicolasbejean_categorywidget_store')], 'store_id') ->join( ['ncw' => $this->getMainTable()], 'ncws.' . $linkField . ' = ncw.' . $linkField, [] ) ->where('ncw.' . $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; } }