より制限された管理者ユーザーを使用すると、コレクションが失敗します
-
16-10-2019 - |
質問
カスタムレポートの実装に役立つ次のコレクションがあります。
<?php
class VMR_Customreports_Model_Resource_Productsordered_Collection
extends Mage_Reports_Model_Resource_Order_Collection
{
public function __construct()
{
parent::__construct();
$this->_init('sales/order_item');
}
public function setDateRange($from, $to)
{
$this->_reset();
$this->getSelect()
->joinInner(
array('i' => $this->getTable('sales/order_item')),
'i.`order_id` = main_table.`entity_id`'
)
->where("main_table.created_at BETWEEN '" . $from . "' AND '" . $to . "'")
->where('main_table.status != \'canceled\'')
->where('main_table.customer_email NOT LIKE \'%@v2cigs.%\'')
->where('i.parent_item_id IS NULL')
->columns(array(
'myname' => 'i.name',
'ordered_qty' => 'sum(i.qty_ordered)',
'ordered_money' => 'sum(i.`price`*i.qty_ordered)'))
->group('i.name');
return $this;
}
public function setStoreIds($storeIds)
{
if ($storeIds)
$this->addAttributeToFilter('i.store_id', array('in' => (array)$storeIds));
return $this;
}
}
完全な管理者としてログインすると、適切なデータが選択されますが、より制限されたユーザーとしてログインすると、「整合性制約違反:1052列「store_id」についてエラーが発生します。
Order_ItemテーブルとOrderテーブルの両方にStore_idが存在することについて話していることを理解できますが、使用時に引っ張るテーブルを指定しています store_id
.
さらに、エラーは結合時に発生します。 store_idコードにコメントすると、エラーが発生します。なんで?
解決
Enterprise Editionを使用している場合、 AdminGws
モジュールはストアスコープフィルターを適用しているため、管理者は表示されているデータのみにアクセスできます。
また、あなたはおそらくあなたを削除したいと思うでしょう __construct()
方法。いくつかの追加情報については、以下を参照してください。
バックグラウンド:
あなたは伸びています Mage_Reports_Model_Resource_Order_Collection
。このクラスはを使用します sales/order
テーブル(つまり、 sales_flat_order
メインテーブルとして。
$this->getSelect()->from(array('main_table' => $this->getMainTable()));
メインテーブルは、実際に関連するリソースモデルから取得されます。
public function getMainTable()
{
if ($this->_mainTable === null) {
$this->setMainTable($this->getResource()->getMainTable());
}
return $this->_mainTable;
}
そのため、リソースモデルはメインテーブル名を提供する責任があります。
Mage::getResourceModel($this->getResourceModelName())
リソースモデルを収集するために使用されます。
だから何をしますか getResourceModelName()
戻る?
によって設定された値を返します _init()
電話。
protected function _init($model, $resourceModel = null)
{
$this->setModel($model);
if (is_null($resourceModel)) {
$resourceModel = $model;
}
$this->setResourceModel($resourceModel);
return $this;
}
あなたのクラスでは、あなたはそれを無効にしています _init()
親クラスの呼び出し:
$this->_init('sales/order_item');
実際には、コレクションがテーブルを返す注文アイテムリソースモデルを使用する必要があることを指定しています sales/order_item
メインテーブルとして。
あなたのためです _init()
あなたが参加していると呼びます sales_flat_order_item
それ自体のテーブル。
削除してそれを修正します _init()
電話、または実際には __construct()
オーバーライドすると、おそらくあなたのためにその問題を修正します。
他のヒント
私がこれを行う場合:
public function addStoreAttributeToFilter($collection)
{
if($collection->getModelName() == 'sales/order' || $collection->getModelName() == 'sales/order_item')
{
$collection->addFieldToFilter('main_table.store_id', array('in' => $this->_role->getStoreIds()));
}
else
{
$collection->addAttributeToFilter('store_id', array('in' => $this->_role->getStoreIds()));
}
}
AdmingWs/Model/Collections.phpで
そして、私のコレクションでは、$ this-> _ init( 'sales/order_item')を行うコンストラクターを作成します。
コンストラクターの部分は私には意味がありませんが、私はそれについて個別に尋ねます。
今日、私は同様の問題に直面しました。電源を)いれる、(電気・テレビなどを)つける $_logAllQueries
@vinaiが示唆したように、それを示しました Enterprise_AdminGws
私のコレクションをフィルタリングしていました store_id
. 。追加して修正しました:
$collection->addFilterToMap('store_id', 'main_table.store_id');
直前に $this->setCollection($collection);