Sind Sammlungen in Magento 2 Geschichte?

25

Ich weiß, dass eine Menge Code, der derzeit in Magento 2 (2.1.2) enthalten ist, mehr oder weniger aus Magento 1 portiert ist und dass in Zukunft eine Menge Code durch ein Äquivalent ersetzt wird. In diesem Zusammenhang frage ich mich, wie die Zukunft der Sammlungen in Magento 2 aussehen wird.

Lassen Sie mich erklären:

Magento 1:

In Magento 1 werden wir verwendet, um eine Sammlung wie diese zu erhalten:

$products = Mage::getModel('catalog/product')->getCollection();

Wir könnten dann Filter und andere Operationen auf die Sammlung anwenden:

$products->addAttributeToFilter('price', ['gteq' => 10]);
$products->addFieldToFilter('created_at', ['lt' => '2016-10-10']);
$products->setPageSize(10);
// ... etc ...

Und zu guter Letzt würde unsere Kollektion die Modelle zurückgeben:

foreach ($products as $product) {
    echo get_class($product); // Mage_Catalog_Model_Product
}

Magento 2:

Magento fügt viele neue Abstraktionsebenen hinzu und implementiert eine solidere Arbeitsweise. Dies bedeutet, dass wir eine Liste von Entitäten aus einem Repository abfragen müssen:

$productResults = $this->productRepository->getList($searchCriteria);

Wenn wir Filter anwenden möchten verwenden wir eine Kombination aus der SearchCriteriaBuilder, die FilterGroupBuilder, das FilterBuilderund das SortOrderBuilder:

$this->searchCriteriaBuilder->addSortOrder(
    $this->sortOrderBuilder
        ->setField('created_at')
        ->setAscendingDirection()
        ->create()
);
$priceFilter = $this->filterBuilder
    ->setField('price')
    ->setValue(10)
    ->setConditionType('gteq')
    ->create();
$createdAtFilter = $this->filterBuilder
    ->setField('created_at')
    ->setValue('2016-10-10')
    ->setConditionType('lt')
    ->create();
$filterGroups = [
    $this->filterGroupBuilder->addFilter($priceFilter)->create(),
    $this->filterGroupBuilder->addFilter($createdAtFilter)->create()
];

Und wenn wir über unsere Ergebnisse iterieren möchten, erhalten wir Datenmodelle, keine tatsächlichen (vererbten) Modelle:

foreach ($productResults->getItems() as $product) {
    echo get_class($product); // \Magento\Catalog\Model\Data\Product
}

Diese Art der Abstraktion folgt dem SOLID-Prinzip und umfasst das Prinzip „Komposition über Vererbung“ . Alle 'exotischen' Operationen, die ansonsten für die Sammlung ausgeführt würden (wie zum Beispiel Joins), werden intern im Repository ausgeführt, was die Verwendung auch außerhalb des Moduls erleichtert.

Die Frage:

All dies lässt mich wundern: Gibt es bei dem gesamten Repository- / Datenmodell-Ansatz in der Zukunft einen Raum für Sammlungen in Magento 2? Sollen Sammlungen nur intern vom Modul selbst und nicht außerhalb verwendet werden? Oder werden die zugunsten des Entity Managers abgelehnt?

Wenn Sie Datenmodelle einbeziehen möchten, müssen Sie derzeit noch ein geerbtes Modell (geerbt von \Magento\Framework\Model\AbstractModel) erstellen , damit die Sammlung funktioniert (da Magento\Framework\Data\Collection::setItemObjectClassdas Modell erweitert werden muss Magento\Framework\DataObject). Und Sie müssen eine Sammlung erstellen, um in Ihrem Repository filtern zu können. Andererseits müssen Sie im Repository Ihr (reguläres) Modell in ein Datenmodell "konvertieren".

Oder müssen wir es wie das Order Repository implementieren, in dem die getList()Rückgaben eine Instanz von sind Magento\Sales\Api\Data\OrderSearchResultInterface, aber unter Wasser sind die Suchergebnisse nichts anderes als eine reguläre Sammlung, die diese Schnittstelle implementiert. Unterhaltsame Tatsache: In den Suchergebnissen wird angegeben, dass ein Array von Datenmodellen ( Magento\Sales\Api\Data\OrderInterface[]) zurückgegeben wird. Wenn Sie jedoch den Code analysieren, getItems()wird ausgeführt, Magento\Framework\Data\Collection::getItems()wodurch nicht die Datenmodelle, sondern die Ordnungsmodelle (wie von festgelegt Magento\Sales\Model\ResourceModel\Order\Collection::_construct()) zurückgegeben werden. Soviel zu 'Komposition über Vererbung'.

Viele Fragen zur richtigen Vorgehensweise in Magento 2. Wiederum gibt es 100 Möglichkeiten, das Gleiche zu tun, aber was ist "The Magento Way"? Oder bin ich hier einfach total auf dem falschen Weg?

Giel Berkers
quelle
2
Hier die wirklichen Fragen stellen +1. Ich würde wirklich eine Antwort des Kernentwicklers hier lieben
Marius
Ich glaube, der Plan sieht vor, dass Sammlungen auslaufen. Wie Sie jedoch bemerkt haben, ist dies bei weitem noch nicht abgeschlossen, und es gibt viele Bereiche, die offenbar in verschiedenen Umgestaltungszuständen sind (da die stabile API Magento \ Sales \ Api \ Data \ OrderSearchResultInterface lautet, kann Magento das ersetzen, was passiert später leichter unter der Haube). Es hilft nicht, dass die verschiedenen Implementierungen von getList noch nicht so leistungsfähig sind, wie wir es derzeit mit Sammlungen tun können. Die Inkonsistenz, die Sie im Zusammenhang mit der angegebenen Rendite festgestellt haben, ist möglicherweise für ein Problem mit Github angemessen.
Kristof bei Fooman

Antworten:

16

Sammlungen werden jetzt nicht mehr unterstützt. Während einige Module bereits Servicevertrags-APIs verfügbar machen, machen andere weiterhin nur Modell- / Erfassungs-APIs verfügbar.

Der Plan ist:

  1. Spiegeln Sie den aktuellen Status mit einer besseren Abdeckung durch @api wider: Kommentieren Sie abstrakte Sammlungen und bestimmte Sammlungen in einigen Modulen mit @api
  2. Verbessern Sie das Persistenz-Framework, um die einfache Erstellung von Serviceverträgen zu ermöglichen, ohne auf vererbungsbasierte APIs angewiesen zu sein: Sammlungen, Modelle, Ressourcenmodelle
  3. Veraltete Abstract-Sammlung, um die auf Sammlungen basierende Implementierung von Serviceverträgen nicht zu fördern
  4. Geben Sie nach und nach neuere Versionen von Modulen mit Servicevertrags-APIs frei

Sammlungen werden also irgendwann veraltet sein, aber jetzt sind sie eine der Magento 2-APIs.

Für die Implementierung von Serviceverträgen sind - Modelle und Sammlungen die einzige bequeme Möglichkeit, sie in Magento <= 2.1 zu implementieren. Serviceverträge sind nur Schnittstellen. Ihre Implementierung ist nicht Teil der öffentlichen API und kann später geändert werden.

Anton Kril
quelle
1
Danke für deine Antwort. Was raten Sie Entwicklern, die neue Module erstellen? Meine derzeitige Strategie besteht darin, Serviceverträge zu erstellen, die (unter Wasser) immer noch Sammlungen verwenden, da a) das Filtern vereinfacht wird und b) der Entity Manager immer noch zu experimentell / undokumentiert ist. Irgendwann kann das Innenleben durch irgendetwas anderes ersetzt werden, aber die Schnittstelle bleibt gleich. Aber wenn ich Ihre Antwort richtig verstehe, ist das vorerst der richtige Weg, oder?
Giel Berkers
Richtig. Ich habe meine Antwort bearbeitet, um dies widerzuspiegeln.
Anton Kril
1
Was wäre in Anbetracht der obigen Ausführungen der richtige Weg, um Funktionen zu implementieren, die Daten erfordern, die nicht über Serviceverträge abgerufen werden können? Zum Beispiel, wenn für Modul A alle Bestellungen nach Zahlungsmethode gefiltert werden müssen.
Stjepan