Die Sammlung schlägt fehl, wenn ein eingeschränkter Administrator Benutzer verwendet wird
-
16-10-2019 - |
Frage
Ich habe die folgende Sammlung, mit der ein benutzerdefiniertes Bericht implementiert wird.
<?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;
}
}
Wenn ich mich als vollständiger Administrator anmelde, wählt es die richtigen Daten aus, aber wenn ich mich als eingeschränkterer Benutzer anmelde, erhalte ich einen Fehler darüber: "Integritätsbeschränkungsverletzung: 1052 Spalte 'Store_id' in der Klausel, in der Klausel mehrdeutig ist".
Ich kann verstehen, dass es sich um Store_id handelt, die sowohl in der Tabelle Order_Item als auch in der Bestellentabelle vorhanden sind, aber ich spreche die Tabelle an, an der ich bei der Verwendung ziehen soll store_id
.
Darüber hinaus tritt der Fehler direkt beim Join auf. Wenn ich den Code store_id kommentiere, erhalte ich immer noch den Fehler. Wieso den?
Lösung
Wenn Sie die Enterprise Edition verwenden, die AdminGws
Das Modul wendet Store Scope -Filter an, sodass Administratoren nur auf Daten zugreifen können, für die sie zu sehen sind.
Außerdem möchten Sie wahrscheinlich Ihre entfernen __construct()
Methode. Weitere Informationen finden Sie weiter unten.
Hintergrund:
Sie erstrecken sich von Mage_Reports_Model_Resource_Order_Collection
. Diese Klasse verwendet die sales/order
Tabelle (das heißt, sales_flat_order
als Haupttisch.
$this->getSelect()->from(array('main_table' => $this->getMainTable()));
Die Haupttabelle ist tatsächlich aus dem zugehörigen Ressourcenmodell abgerufen:
public function getMainTable()
{
if ($this->_mainTable === null) {
$this->setMainTable($this->getResource()->getMainTable());
}
return $this->_mainTable;
}
Das Ressourcenmodell ist also dafür verantwortlich, den Hauptnamen des Haupttabels zu liefern.
Mage::getResourceModel($this->getResourceModelName())
wird verwendet, um das Ressourcenmodell zu sammeln.
Also was tut? getResourceModelName()
Rückkehr?
Es gibt den Wert zurück, der von der festgelegt wurde _init()
Anruf.
protected function _init($model, $resourceModel = null)
{
$this->setModel($model);
if (is_null($resourceModel)) {
$resourceModel = $model;
}
$this->setResourceModel($resourceModel);
return $this;
}
In Ihrer Klasse überschreiben Sie die _init()
Ruf der übergeordneten Klasse:
$this->_init('sales/order_item');
Tatsächlich geben Sie an, dass Ihre Sammlung das Bestellelement -Ressourcenmodell verwenden sollte, das die Tabelle zurückgibt sales/order_item
als Haupttisch.
Wegen deiner _init()
Rufen Sie an, Sie schließen sich der an sales_flat_order_item
Tabelle mit sich selbst.
Beheben Sie dies durch Entfernen der _init()
Rufen Sie an oder tatsächlich das Ganze __construct()
Überschreiben, wird dieses Problem wahrscheinlich für Sie beheben.
Andere Tipps
Wenn ich das mache:
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()));
}
}
In Adminsws/Modell/Collections.php
Und in meiner Sammlung erstellen Sie einen Konstruktor, der $ this-> _ init ('sales/order_item') funktioniert.
Der Konstruktorteil macht für mich keinen Sinn, aber ich werde separat danach fragen.
Heute hatte ich ein ähnliches Problem. Einschalten $_logAllQueries
wie @vinai vorschlug, zeigte das Enterprise_AdminGws
filterte meine Sammlung von store_id
. Ich habe es behoben, indem ich hinzugefügt habe:
$collection->addFilterToMap('store_id', 'main_table.store_id');
Kurz vor dem $this->setCollection($collection);