For now, I am able to use a admin grid to show a custom table(contactus_map_location):
but I want to have a store view column in my grid and according to the cms page module, I should have a separate table(contactus_map_location_store) to join the original table and show it.
I tried to use the method in cms_page module but it does not work. Here comes my code: app\code\Company\Module\etc\di.xml:
Company\Module\Model\Resource\Grid\Collection ContactusGridFilterPool
<!-- Create our type ContactusGridFilterPool -->
<virtualType name="ContactusGridFilterPool" type="Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool">
<arguments>
<argument name="appliers" xsi:type="array">
<item name="regular" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\RegularFilter</item>
<item name="fulltext" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\FulltextFilter</item>
</argument>
</arguments>
</virtualType>
<!-- Type for jobs_department_listing_data_source -->
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
<arguments>
<argument name="collections" xsi:type="array">
<item name="contactus_grid_listing_data_source" xsi:type="string">Company\Module\Model\ResourceModel\Grid\Grid\Collection</item>
</argument>
</arguments>
</type>
<!-- Simulate our class Company\Module\Model\ResourceModel\Grid\Grid\Collection -->
<virtualType name="Company\Module\Model\ResourceModel\Grid\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
<arguments>
<argument name="mainTable" xsi:type="string">contactus_map_location</argument>
<argument name="resourceModel" xsi:type="string">Company\Module\Model\ResourceModel\Grid</argument>
</arguments>
</virtualType>
app\code\Company\Module\Model\ResourceModel\Grid.php:
<?php
namespace Company\Module\Model\ResourceModel;
use \Magento\Framework\Model\ResourceModel\Db\AbstractDb;
/**
* Grid post mysql resource
*/
class Grid extends AbstractDb
{
const GRID_ID = 'entity_id'; // We define the id fieldname
/**
* Prefix of model events names
*
* @var string
*/
protected $_eventPrefix = 'contactus'; // parent value is 'core_abstract'
/**
* Name of the event object
*
* @var string
*/
protected $_eventObject = 'grid'; // parent value is 'object'
/**
* Name of object id field
*
* @var string
*/
protected $_idFieldName = self::GRID_ID;
/**
* Initialize resource model
*
* @return void
*/
protected $_store = null;
/**
* Store manager
*
* @var \Magento\Store\Model\StoreManagerInterface
*/
protected $_storeManager;
/**
* @var \Magento\Framework\Stdlib\DateTime
*/
protected $dateTime;
public function __construct(
\Magento\Framework\Model\ResourceModel\Db\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\Stdlib\DateTime $dateTime,
$connectionName = null
) {
parent::__construct($context, $connectionName);
$this->_storeManager = $storeManager;
$this->dateTime = $dateTime;
}
protected function _construct()
{
$this->_init('contactus_map_location', 'entity_id');
}
protected function _afterLoad(\Magento\Framework\Model\AbstractModel $object)
{
if ($object->getId()) {
$stores = $this->lookupStoreIds($object->getId());
$object->setData('store_id', $stores);
}
return parent::_afterLoad($object);
}
public function lookupStoreIds($location_id)
{
$connection = $this->getConnection();
$select = $connection->select()->from(
$this->getTable('contactus_map_location_store'),
'store_id'
)->where(
'location_id = ?',
(int)$location_id
);
return $connection->fetchCol($select);
}
}
app\code\Company\Module\Model\ResourceModel\AbstractCollection.php:
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Company\Module\Model\ResourceModel;
/**
* Abstract collection of CMS pages and blocks
*/
abstract class AbstractCollection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
/**
* Store manager
*
* @var \Magento\Store\Model\StoreManagerInterface
*/
protected $storeManager;
/**
* @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
* @param \Psr\Log\LoggerInterface $logger
* @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
* @param \Magento\Framework\Event\ManagerInterface $eventManager
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\DB\Adapter\AdapterInterface|null $connection
* @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb|null $resource
*/
public function __construct(
\Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
\Psr\Log\LoggerInterface $logger,
\Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
\Magento\Framework\Event\ManagerInterface $eventManager,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\DB\Adapter\AdapterInterface $connection = null,
\Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
) {
parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
$this->storeManager = $storeManager;
}
/**
* Perform operations after collection load
*
* @param string $tableName
* @param string $columnName
* @return void
*/
protected function performAfterLoad($tableName, $columnName)
{
$items = $this->getColumnValues($columnName);
if (count($items)) {
$connection = $this->getConnection();
$select = $connection->select()->from(['cms_entity_store' => $this->getTable($tableName)])
->where('cms_entity_store.' . $columnName . ' IN (?)', $items);
$result = $connection->fetchPairs($select);
if ($result) {
foreach ($this as $item) {
$entityId = $item->getData($columnName);
if (!isset($result[$entityId])) {
continue;
}
if ($result[$entityId] == 0) {
$stores = $this->storeManager->getStores(false, true);
$storeId = current($stores)->getId();
$storeCode = key($stores);
} else {
$storeId = $result[$item->getData($columnName)];
$storeCode = $this->storeManager->getStore($storeId)->getCode();
}
$item->setData('_first_store_id', $storeId);
$item->setData('store_code', $storeCode);
$item->setData('store_id', [$result[$entityId]]);
}
}
}
}
/**
* 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|\Magento\Store\Model\Store $store
* @param bool $withAdmin
* @return $this
*/
abstract public function addStoreFilter($store, $withAdmin = true);
/**
* Perform adding filter by store
*
* @param int|array|\Magento\Store\Model\Store $store
* @param bool $withAdmin
* @return void
*/
protected function performAddStoreFilter($store, $withAdmin = true)
{
if ($store instanceof \Magento\Store\Model\Store) {
$store = [$store->getId()];
}
if (!is_array($store)) {
$store = [$store];
}
if ($withAdmin) {
$store[] = \Magento\Store\Model\Store::DEFAULT_STORE_ID;
}
$this->addFilter('store', ['in' => $store], 'public');
}
/**
* Join store relation table if there is store filter
*
* @param string $tableName
* @param string $columnName
* @return void
*/
protected function joinStoreRelationTable($tableName, $columnName)
{
if ($this->getFilter('store')) {
$this->getSelect()->join(
['store_table' => $this->getTable($tableName)],
'main_table.' . $columnName . ' = store_table.' . $columnName,
[]
)->group(
'main_table.' . $columnName
);
}
parent::_renderFiltersBefore();
}
/**
* Get SQL for get record count
*
* Extra GROUP BY strip added.
*
* @return \Magento\Framework\DB\Select
*/
public function getSelectCountSql()
{
$countSelect = parent::getSelectCountSql();
$countSelect->reset(\Magento\Framework\DB\Select::GROUP);
return $countSelect;
}
}
app\code\Company\Module\Model\ResourceModel\Grid\Collection.php:
<?php
namespace Company\Module\Model\ResourceModel\Grid;
use \Company\Module\Model\ResourceModel\AbstractCollection;
class Collection extends AbstractCollection
{
protected $_idFieldName = 'entity_id';
/**
* Define resource model
*
* @return void
*/
protected function _construct()
{
$this->_init('Company\Module\Model\Grid', 'Company\Module\Model\ResourceModel\Grid');
}
public function addStoreFilter($store, $withAdmin = true)
{
if (!$this->getFlag('store_filter_added')) {
$this->performAddStoreFilter($store, $withAdmin);
}
return $this;
}
}
app\code\Company\Module\Model\ResourceModel\Grid\CollectionFactory.php:
<?php
namespace Company\Module\Model\ResourceModel\Grid;
class CollectionFactory
{
/**
* Object Manager instance
*
* @var \Magento\Framework\ObjectManagerInterface
*/
protected $_objectManager = null;
/**
* Instance name to create
*
* @var string
*/
protected $_instanceName = null;
/**
* Factory constructor
*
* @param \Magento\Framework\ObjectManagerInterface $objectManager
* @param string $instanceName
*/
public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager, $instanceName = '\\Company\\Module\\Model\\ResourceModel\\Grid\\Collection')
{
$this->_objectManager = $objectManager;
$this->_instanceName = $instanceName;
}
/**
* Create class instance with specified parameters
*
* @param array $data
* @return \Company\Module\Model\ResourceModel\Department\Collection
*/
public function create(array $data = array())
{
return $this->_objectManager->create($this->_instanceName, $data);
}
}