I created eav entity module. But, when I use this addAttributeToFilter, addAttributeToSelect, addFieldToFilter
function in my custom module collection. It's not working.
My collection file :
I extend Magento\Eav\Model\Entity\Collection\AbstractCollection
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace VendorName\ModuleName\Model\ResourceModel\Mainpage;
use Magento\Eav\Model\Config;
use Magento\Eav\Model\Entity\Collection\AbstractCollection;
use Magento\Eav\Model\EntityFactory as EavEntityFactory;
use Magento\Eav\Model\ResourceModel\Helper;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
use Magento\Framework\Data\Collection\EntityFactory;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\Event\ManagerInterface;
use Magento\Framework\Validator\UniversalFactory;
use Magento\Store\Model\StoreManagerInterface;
use Psr\Log\LoggerInterface;
/**
* Class Collection
* @package VendorName\ModuleName\Model\ResourceModel\Mainpage
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Collection extends AbstractCollection
{
/**
* @var string
*/
protected $_idFieldName = 'entity_id';
/**
* @var $_storeId
*/
protected $_storeId;
/**
* @var StoreManagerInterface
*/
protected $_storeManager;
const KEY_MAIN_VIDEO_TITLE = 'main_video_title';
/**
* @param EntityFactory $entityFactory
* @param LoggerInterface $logger
* @param FetchStrategyInterface $fetchStrategy
* @param ManagerInterface $eventManager
* @param Config $eavConfig
* @param ResourceConnection $resource
* @param EavEntityFactory $eavEntityFactory
* @param Helper $resourceHelper
* @param UniversalFactory $universalFactory
* @param StoreManagerInterface $storeManager
* @param AdapterInterface $connection
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
EntityFactory $entityFactory,
LoggerInterface $logger,
FetchStrategyInterface $fetchStrategy,
ManagerInterface $eventManager,
Config $eavConfig,
ResourceConnection $resource,
EavEntityFactory $eavEntityFactory,
Helper $resourceHelper,
UniversalFactory $universalFactory,
StoreManagerInterface $storeManager,
AdapterInterface $connection = null
) {
$this->_storeManager = $storeManager;
parent::__construct(
$entityFactory,
$logger,
$fetchStrategy,
$eventManager,
$eavConfig,
$resource,
$eavEntityFactory,
$resourceHelper,
$universalFactory,
$connection
);
}
/**
* Define resource model
*
* @return void
*/
protected function _construct()
{
$this->_init(\VendorName\ModuleName\Model\Mainpage::class, \VendorName\ModuleName\Model\ResourceModel\Mainpage::class);
}
/**
* Set store scope
*
* @param int|string|\Magento\Store\Model\Store $store
* @return $this
*/
public function setStore($store)
{
$this->setStoreId($this->_storeManager->getStore($store)->getId());
return $this;
}
/**
* Set store scope
*
* @param int|string|\Magento\Store\Api\Data\StoreInterface $storeId
* @return $this
*/
public function setStoreId($storeId)
{
if ($storeId instanceof \Magento\Store\Api\Data\StoreInterface) {
$storeId = $storeId->getId();
}
$this->_storeId = (int)$storeId;
return $this;
}
/**
* Return current store id
*
* @return int
*/
public function getStoreId()
{
if ($this->_storeId === null) {
$this->setStoreId($this->_storeManager->getStore()->getId());
}
return $this->_storeId;
}
/**
* Retrieve default store id
*
* @return int
*/
public function getDefaultStoreId()
{
return \Magento\Store\Model\Store::DEFAULT_STORE_ID;
}
/**
* Set main video title
*
* @param int $mainvideoTitle
* @return $this
*/
public function setMainVideoTitle($mainvideoTitle)
{
return $this->setData(self::KEY_MAIN_VIDEO_TITLE, $mainvideoTitle);
}
/**
* {@inheritdoc}
*/
public function getMainVideoTitle()
{
return $this->getData(self::KEY_MAIN_VIDEO_TITLE);
}
/**
* Retrieve attributes load select
*
* @param string $table
* @param array|int $attributeIds
* @return \Magento\Eav\Model\Entity\Collection\AbstractCollection
*/
protected function _getLoadAttributesSelect($table, $attributeIds = [])
{
if (empty($attributeIds)) {
$attributeIds = $this->_selectAttributes;
}
$storeId = $this->getStoreId();
$connection = $this->getConnection();
$entityTable = $this->getEntity()->getEntityTable();
$indexList = $connection->getIndexList($entityTable);
$entityIdField = $indexList[$connection->getPrimaryKeyName($entityTable)]['COLUMNS_LIST'][0];
if ($storeId) {
$joinCondition = [
't_s.attribute_id = t_d.attribute_id',
"t_s.{$entityIdField} = t_d.{$entityIdField}",
$connection->quoteInto('t_s.store_id = ?', $storeId),
];
$select = $connection->select()->from(
['t_d' => $table],
['attribute_id']
)->join(
['e' => $entityTable],
"e.{$entityIdField} = t_d.{$entityIdField}",
['e.entity_id']
)->where(
"e.entity_id IN (?)",
array_keys($this->_itemsById)
)->where(
't_d.attribute_id IN (?)',
$attributeIds
)->joinLeft(
['t_s' => $table],
implode(' AND ', $joinCondition),
[]
)->where(
't_d.store_id = ?',
$connection->getIfNullSql('t_s.store_id', \Magento\Store\Model\Store::DEFAULT_STORE_ID)
);
} else {
$select = $connection->select()->from(
['t_d' => $table],
['attribute_id']
)->join(
['e' => $entityTable],
"e.{$entityIdField} = t_d.{$entityIdField}",
['e.entity_id']
)->where(
"e.entity_id IN (?)",
array_keys($this->_itemsById)
)->where(
'attribute_id IN (?)',
$attributeIds
)->where(
'store_id = ?',
$this->getDefaultStoreId()
);
}
return $select;
}
/**
* @param \Magento\Framework\DB\Select $select
* @param string $table
* @param string $type
* @return \Magento\Framework\DB\Select
*/
protected function _addLoadAttributesSelectValues($select, $table, $type)
{
$storeId = $this->getStoreId();
if ($storeId) {
$connection = $this->getConnection();
$valueExpr = $connection->getCheckSql('t_s.value_id IS NULL', 't_d.value', 't_s.value');
$select->columns(
['default_value' => 't_d.value', 'store_value' => 't_s.value', 'value' => $valueExpr]
);
} else {
$select = parent::_addLoadAttributesSelectValues($select, $table, $type);
}
return $select;
}
/**
* Adding join statement to collection select instance
*
* @param string $method
* @param object $attribute
* @param string $tableAlias
* @param array $condition
* @param string $fieldCode
* @param string $fieldAlias
* @return \Magento\Eav\Model\Entity\Collection\AbstractCollection
*/
protected function _joinAttributeToSelect($method, $attribute, $tableAlias, $condition, $fieldCode, $fieldAlias)
{
if (isset($this->_joinAttributes[$fieldCode]['store_id'])) {
$storeId = $this->_joinAttributes[$fieldCode]['store_id'];
} else {
$storeId = $this->getStoreId();
}
$connection = $this->getConnection();
if ($storeId != $this->getDefaultStoreId() && !$attribute->isScopeGlobal()) {
$defCondition = '(' . implode(') AND (', $condition) . ')';
$defAlias = $tableAlias . '_default';
$defAlias = $this->getConnection()->getTableName($defAlias);
$defFieldAlias = str_replace($tableAlias, $defAlias, $fieldAlias);
$tableAlias = $this->getConnection()->getTableName($tableAlias);
$defCondition = str_replace($tableAlias, $defAlias, $defCondition);
$defCondition .= $connection->quoteInto(
" AND " . $connection->quoteColumnAs("{$defAlias}.store_id", null) . " = ?",
$this->getDefaultStoreId()
);
$this->getSelect()->{$method}(
[$defAlias => $attribute->getBackend()->getTable()],
$defCondition,
[]
);
$method = 'joinLeft';
$fieldAlias = $this->getConnection()->getCheckSql(
"{$tableAlias}.value_id > 0",
$fieldAlias,
$defFieldAlias
);
$this->_joinAttributes[$fieldCode]['condition_alias'] = $fieldAlias;
$this->_joinAttributes[$fieldCode]['attribute'] = $attribute;
} else {
$storeId = $this->getDefaultStoreId();
}
$condition[] = $connection->quoteInto(
$connection->quoteColumnAs("{$tableAlias}.store_id", null) . ' = ?',
$storeId
);
return parent::_joinAttributeToSelect($method, $attribute, $tableAlias, $condition, $fieldCode, $fieldAlias);
}
}
How to do that, this all function should be working as like working in product collection and all.
My code :
<?php
namespace VendorName\ModuleName\Controller\Index;
class Index extends \Magento\Framework\App\Action\Action
{
/**
* @var \Magento\Framework\View\Result\PageFactory
*/
protected $resultPageFactory;
protected $_collectionFactory;
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory,
\VendorName\ModuleName\Model\ResourceModel\Mainpage\CollectionFactory $collectionFactory,
)
{
$this->_collectionFactory = $collectionFactory;
parent::__construct($context);
}
/**
* Default customer account page
*
* @return void
*/
public function execute()
{
$collection = $this->_collectionFactory->create();
$collection->addAttributeToFilter('main_video_title','Main Page Title German'); //main_video_title is my attribute
print_r($collection->getData());
}
}
?>
Tables :
vendor_module_entity :
vendor_module_entity_varchar :
I debug in core function and I get proper query as like product collection query :
SELECT
e
.*, IF(at_name.value_id > 0, at_name.value, at_name_default.value) ASname
FROMcatalog_product_entity
ASe
INNER JOINcatalog_product_entity_varchar
ASat_name_default
ON (at_name_default
.entity_id
=e
.entity_id
) AND (at_name_default
.attribute_id
= '73') ANDat_name_default
.store_id
= 0
LEFT JOINcatalog_product_entity_varchar
ASat_name
ON (at_name
.entity_id
=e
.entity_id
) AND (at_name
.attribute_id
= '73') AND (at_name
.store_id
= 1) WHERE (IF(at_name.value_id > 0, at_name.value, at_name_default.value) = 'Push It Messenger Bag')
It returns 1 record
============================
My Module Query :
SELECT
e
.*, IF(at_main_video_title.value_id > 0, at_main_video_title.value, at_main_video_title_default.value) ASmain_video_title
FROMvendor_module_entity
ASe
INNER JOINvendor_module_entity_varchar
ASat_main_video_title_default
ON (at_main_video_title_default
.entity_id
=e
.entity_id
) AND (at_main_video_title_default
.attribute_id
= '190') ANDat_main_video_title_default
.store_id
= 0
LEFT JOINvendor_module_entity_varchar
ASat_main_video_title
ON (at_main_video_title
.entity_id
=e
.entity_id
) AND (at_main_video_title
.attribute_id
= '190') AND (at_main_video_title
.store_id
= 1) WHERE (IF(at_main_video_title.value_id > 0, at_main_video_title.value, at_main_video_title_default.value) = 'Main Page Title German')
It returns blank array.
Best Answer
The collection works correct in my opinion, the data you look for is in store 2. So you just need to set the store id in your collection.