Skip to content
This repository has been archived by the owner on Jul 7, 2023. It is now read-only.

Commit

Permalink
Merge pull request #1 from weprovide/feature/store_link_classes
Browse files Browse the repository at this point in the history
Adding 2 abstract classes that can be used for entities that have a l…
  • Loading branch information
Mischa Braam authored May 18, 2022
2 parents bf70eeb + 64e23eb commit 937f1c8
Show file tree
Hide file tree
Showing 3 changed files with 284 additions and 2 deletions.
184 changes: 184 additions & 0 deletions Model/ResourceModel/AbstractStoreLinkedCollection.php
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
);
}
}
}
98 changes: 98 additions & 0 deletions Model/ResourceModel/AbstractStoreLinkedResource.php
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;
}
}
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "weprovide/magento2-core",
"description": "",
"type": "magento2-module",
"version": "1.1.0",
"version": "1.2.0",
"license": "MIT",
"authors": [
{
Expand All @@ -22,4 +22,4 @@
"registration.php"
]
}
}
}

0 comments on commit 937f1c8

Please sign in to comment.