Die Aufgabe ist trivial. Ich muss eine Liste der Produkte für eine bestimmte Store-Ansicht mit aktiviertem Flat-Katalog abrufen. Die naheliegendste Lösung ist die folgende:
$collection = Mage::getResourceModel('catalog/product_collection')
->setStore($storeId);
Tatsächlich macht die setStore()
Methode hier keinen Unterschied, da sie aufgerufen wird, nachdem die _initSelect()
Methode Mage_Catalog_Model_Resource_Product_Collection
anhand der Geschäfts-ID den Namen der flachen Tabelle abgerufen hat. Da die Filial-ID noch nicht festgelegt ist, wird die aktuelle Filial-ID verwendet.
Die naheliegende Problemumgehung besteht darin, eine aktuelle Geschäfts-ID festzulegen, bevor Sie ein Modell abrufen.
Mage::app()->setCurrentStore($storeId);
$collection = Mage::getResourceModel('catalog/product_collection');
Es wird klappen. Aber nur, wenn Sie einmal eine Sammlung benötigen. Wenn Sie eine Sammlung auf den neuesten Stand bringen möchten oder nur zwei aufeinanderfolgende Sammlungen benötigen, können Sie keinen bestimmten Speicher für diese festlegen.
Der Grund dafür ist, dass die Mage_Catalog_Model_Resource_Product_Flat
Klasse eine eigene _storeId
Eigenschaft hat und im Konstruktor auf die aktuelle Geschäfts-ID festgelegt ist. Deshalb wird es beim ersten Mal eingestellt. Dann wird aus irgendeinem Grund (der Himmel weiß, ich hoffe, es gibt einen) in Mage_Eav_Model_Entity_Collection_Abstract::_init
jedem Ressourcenmodul als Singleton abgerufen. Also kein Konstruktor für den 2. Aufruf.
Das alles sieht so falsch aus, dass ich ziemlich sicher bin, dass ich falsch liege und es kein weiterer Magento-Bug (oder zwei) ist. Ich hoffe, jemand kann Licht ins Dunkel bringen.
quelle
Antworten:
Welche Version von Magento ist das? Dies sind meine Ergebnisse für Magento 1.9:
Flacher Katalog aktiviert:
Der flache Katalog ist indexiert:
Einige Datensätze in einer bestimmten Geschäftsansicht:
Code verwendet:
Ergebnis ist wie erwartet:
bearbeiten:
Egal, flacher Katalog ist speziell für den Admin Store verboten:
Untersuchung ...
edit2:
Sieht so aus, als hättest du recht.
_initSelect
wird aufgerufen, bevor die storeId geändert werden kann, mit der der Tabellenname generiert wird.Natürlich können wir (wenn wir nicht den Weg des Umschreibens gehen wollen):
getSelect()
, mache einen Reset und setze einen neuen von ()$collection->getEntity()->setStoreId(123)
und rufen Sie dann_initSelect
erneut mit Reflection an__construct
, zu verzögern_initSelect
usw.).setCurrentStore
jedes Mal an, wenn wir die Sammlung erstellen.Aber diese fühlen sich alle sehr abgefahren an ... Sorry, das könnte eine unbefriedigende Antwort sein :-(
edit3:
Um zumindest eine Antwort zu geben:
Bitte nicht benutzen ;-)
quelle
product_collection
der Konstruktor akzeptiert ein Ressourcenmodell als Argument. Wenn Sie also eine erstellenProduct_Resource_Flat
, ihre Geschäfts-ID festlegen, sie klonen und eine andere Geschäfts-ID festlegen und sie dann an den Auflistungskonstruktor übergeben, ist dies möglich?Ich betrachte dies als zwei Fehler in Magento.
Erstens können Sie die Geschäfts-ID nicht für die
catalog/product
Sammlung festlegen . Und das zweite ist, dass Sie als Nicht-Singleton absolut kein Ressourcenmodell erhalten können.Es ist also eine blöde Lösung, das Modell zweimal zu instanziieren. Das erste Mal, wenn die Geschäfts-ID festgelegt werden kann, wird sie von der zweiten Instanz verwendet:
quelle
Interessanterweise wird die verwendete flache Tabelle einmal festgelegt und nie geändert, was für EAV funktioniert, da sich der Tabellenname nicht ändert, aber nicht für die flache Tabelle, da der Tabellenname die Geschäfts-ID enthält. Eine Problemumgehung wäre, einen Helfer zu erstellen, der die Tabelle im FROM-Teil der Abfrage austauscht. Hier ist ein Beispiel für einen solchen Helfer:
Dann können Sie es einfach mit:
Ich stelle mir vor, dass dies für SQL keine Probleme bereiten würde, da Sie alle Daten von einer einzigen flachen Tabelle abrufen. Da es sich jedoch um einen Singleton handelt, wird der zuletzt verwendete Speicher überall anders verwendet.
Eine alternative Lösung wäre, einen Beobachter zu machen,
catalog_product_collection_load_before
der etwas in der Art macht:Ich bin damit einverstanden, dass Magento-Leute dies in der
_beforeLoad()
Methode beheben sollten .quelle
Warum nicht einen gewöhnlichen Filter verwenden?
$collection->addAttributeToFilter('store_id', $store_id);
store_id wird als reguläre Spalte in der * _eav_entity- Tabelle angegeben, sodass Sie auch danach filtern können. Hat für mich gearbeitet.
quelle
Sei mein Werk diese Lösung mit core / app_emulation:
quelle