This repository has been archived by the owner on Jul 7, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from weprovide/feature/store_link_classes
Adding 2 abstract classes that can be used for entities that have a l…
- Loading branch information
Showing
3 changed files
with
284 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace WeProvide\Core\Model\ResourceModel; | ||
|
||
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\Model\ResourceModel\Db\Collection\AbstractCollection; | ||
use Magento\Store\Model\Store; | ||
use Magento\Store\Model\StoreManagerInterface; | ||
use Psr\Log\LoggerInterface; | ||
|
||
/** | ||
* This class can be used for collection for entities which have a store view link | ||
*/ | ||
abstract class AbstractStoreLinkedCollection extends AbstractCollection | ||
{ | ||
/** @var string */ | ||
protected const STORE_LINK_TABLE_ALIAS = 'store_link_table'; | ||
|
||
/** | ||
* @var StoreManagerInterface | ||
*/ | ||
protected $storeManager; | ||
|
||
/** | ||
* @var MetadataPool | ||
*/ | ||
protected $metadataPool; | ||
|
||
/** | ||
* @param EntityFactoryInterface $entityFactory | ||
* @param LoggerInterface $logger | ||
* @param FetchStrategyInterface $fetchStrategy | ||
* @param ManagerInterface $eventManager | ||
* @param StoreManagerInterface $storeManager | ||
* @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 | ||
) { | ||
parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource); | ||
$this->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 | ||
); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace WeProvide\Core\Model\ResourceModel; | ||
|
||
use Magento\Framework\EntityManager\EntityManager; | ||
use Magento\Framework\EntityManager\MetadataPool; | ||
use Magento\Framework\Model\AbstractModel; | ||
use Magento\Framework\Model\ResourceModel\Db\AbstractDb; | ||
use Magento\Framework\Model\ResourceModel\Db\Context; | ||
|
||
/** | ||
* This class can be used for entities which have a store view link | ||
*/ | ||
abstract class AbstractStoreLinkedResource extends AbstractDb | ||
{ | ||
/** | ||
* @var EntityManager | ||
*/ | ||
protected $entityManager; | ||
|
||
/** | ||
* @var MetadataPool | ||
*/ | ||
protected $metadataPool; | ||
|
||
/** @var string */ | ||
protected $storeLinkMainTable = null; | ||
|
||
/** @var string */ | ||
protected $storeLinkLinkTable = null; | ||
|
||
/** @var string */ | ||
protected $metadataClassName = null; | ||
|
||
/** @var string */ | ||
protected $storeLinkIdFieldName = 'store_id'; | ||
|
||
/** | ||
* @param Context $context | ||
* @param EntityManager $entityManager | ||
* @param null $resourcePrefix | ||
*/ | ||
public function __construct( | ||
Context $context, | ||
EntityManager $entityManager, | ||
MetadataPool $metadataPool, | ||
$resourcePrefix = null | ||
) { | ||
parent::__construct($context, $resourcePrefix); | ||
$this->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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters