From 64e23eb87f171faa1f86a4e948e115390408c71f Mon Sep 17 00:00:00 2001 From: Sander Merks Date: Wed, 18 May 2022 13:18:14 +0200 Subject: [PATCH] Adding 2 abstract classes that can be used for entities that have a link with store views --- .../AbstractStoreLinkedCollection.php | 184 ++++++++++++++++++ .../AbstractStoreLinkedResource.php | 98 ++++++++++ composer.json | 4 +- 3 files changed, 284 insertions(+), 2 deletions(-) create mode 100644 Model/ResourceModel/AbstractStoreLinkedCollection.php create mode 100755 Model/ResourceModel/AbstractStoreLinkedResource.php diff --git a/Model/ResourceModel/AbstractStoreLinkedCollection.php b/Model/ResourceModel/AbstractStoreLinkedCollection.php new file mode 100644 index 0000000..092360e --- /dev/null +++ b/Model/ResourceModel/AbstractStoreLinkedCollection.php @@ -0,0 +1,184 @@ +storeManager = $storeManager; + $this->metadataPool = $metadataPool; + } + + /** + * Perform operations after collection load + * + * @param string $tableName + * @param string|null $linkField + * @return void + */ + protected function performAfterLoad($tableName, $linkField) + { + $linkedIds = $this->getColumnValues($linkField); + if (count($linkedIds)) { + $connection = $this->getConnection(); + $select = $connection->select()->from([static::STORE_LINK_TABLE_ALIAS => $this->getTable($tableName)]) + ->where(static::STORE_LINK_TABLE_ALIAS . '.' . $linkField . ' IN (?)', $linkedIds); + $result = $connection->fetchAll($select); + + $storesData = []; + foreach ($result as $storeData) { + $storesData[$storeData[$linkField]][] = $storeData['store_id']; + } + + foreach ($this as $item) { + $linkedId = $item->getData($linkField); + $storeIds = $storesData[$linkedId] ?? [Store::DEFAULT_STORE_ID]; + + $storeIdKey = array_search(Store::DEFAULT_STORE_ID, $storeIds, true); + if ($storeIdKey !== false) { + $stores = $this->storeManager->getStores(false, true); + $storeId = current($stores)->getId(); + $storeCode = key($stores); + } else { + $storeId = current($storeIds); + $storeCode = $this->storeManager->getStore($storeId)->getCode(); + } + $item->setData('_first_store_id', $storeId); + $item->setData('store_code', $storeCode); + $item->setData('store_id', $storeIds); + } + } + } + + /** + * Add field filter to collection + * + * @param array|string $field + * @param string|int|array|null $condition + * @return $this + */ + 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 + */ + public function addStoreFilter($store, $withAdmin = true) + { + if (!$this->getFlag('store_filter_added')) { + $this->performAddStoreFilter($store, $withAdmin); + $this->setFlag('store_filter_added', true); + } + + return $this; + } + + /** + * 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; + } + + $conditions = [['in' => $store]]; + + // When results when the default store are retrieved, also search for where no store was set yet + if (in_array(Store::DEFAULT_STORE_ID, $store)) { + $conditions[] = ['null' => true]; + } + + $this->addFilter('store', $conditions, '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()->joinLeft( + ['store_table' => $this->getTable($tableName)], + 'main_table.' . $linkField . ' = store_table.' . $linkField, + [] + )->group( + 'main_table.' . $linkField + ); + } + } +} diff --git a/Model/ResourceModel/AbstractStoreLinkedResource.php b/Model/ResourceModel/AbstractStoreLinkedResource.php new file mode 100755 index 0000000..5801000 --- /dev/null +++ b/Model/ResourceModel/AbstractStoreLinkedResource.php @@ -0,0 +1,98 @@ +entityManager = $entityManager; + $this->metadataPool = $metadataPool; + } + + /** + * Initialize resource model. + */ + protected function _construct() + { + $this->_init($this->storeLinkMainTable, $this->_idFieldName); + } + + /** + * Get store ids to which specified item is assigned + * + * @param int $id + * @return array + */ + public function lookupStoreIds($id) + { + $connection = $this->getConnection(); + + $entityMetadata = $this->metadataPool->getMetadata($this->metadataClassName); + $linkField = $entityMetadata->getLinkField(); + + $select = $connection->select() + ->from(['store_link' => $this->getTable($this->storeLinkLinkTable)], $this->storeLinkIdFieldName) + ->join( + ['main_table' => $this->getMainTable()], + 'store_link.' . $linkField . ' = main_table.' . $linkField, + [] + ) + ->where('main_table.' . $entityMetadata->getIdentifierField() . ' = :entity_id'); + + return $connection->fetchCol($select, ['entity_id' => (int)$id]); + } + + /** + * @param AbstractModel $object + * @return $this|AbstractStoreLinkedResource + */ + public function save(AbstractModel $object) + { + $this->entityManager->save($object); + return $this; + } +} diff --git a/composer.json b/composer.json index 29949a3..22d7cdf 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "weprovide/magento2-core", "description": "", "type": "magento2-module", - "version": "1.1.0", + "version": "1.2.0", "license": "MIT", "authors": [ { @@ -22,4 +22,4 @@ "registration.php" ] } -} \ No newline at end of file +}