Le raccolte sono cronologiche in Magento 2?


25

So che un sacco di codice che è attualmente in Magento 2 (2.1.2) è più o meno portato da Magento 1 e che molto codice verrà sostituito da un equivalente in futuro. In questo aspetto, mi chiedo quale sia il futuro delle collezioni in Magento 2.

Lasciatemi spiegare:

Magento 1:

In Magento 1 siamo abituati a ottenere una raccolta come questa:

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

Potremmo quindi applicare filtri e altre operazioni alla raccolta:

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

E, ultimo ma non meno importante, la nostra collezione restituirebbe i modelli:

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

Magento 2:

Magento aggiunge molti nuovi livelli di astrazione, implementando un modo di lavorare più SOLIDO. Ciò significa che quando vogliamo un elenco di entità, lo chiediamo a un repository:

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

Se vogliamo applicare filtri utilizziamo una combinazione di SearchCriteriaBuilder, il FilterGroupBuilder, il FilterBuildere il 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()
];

E se vogliamo scorrere i nostri risultati, otteniamo modelli di dati, non modelli effettivi (ereditati):

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

Questo tipo di astrazione segue il principio SOLIDO e abbraccia il principio della "composizione sull'eredità" . Qualsiasi operazione "esotica" che verrebbe altrimenti eseguita sulla raccolta (come i join per gli esempi) viene eseguita internamente nel repository, il che semplifica anche l'utilizzo all'esterno del modulo.

La domanda:

Tutto ciò mi fa meravigliare: con l'intero repository / approccio al modello di dati, c'è spazio nel futuro di Magento 2 per le collezioni? Le raccolte devono essere utilizzate solo internamente dal modulo stesso e non al di fuori di esso? O saranno deprecati a favore del Gestore delle entità?

Attualmente, se si desidera abbracciare i modelli di dati, è comunque necessario creare un modello ereditato (ereditato da \Magento\Framework\Model\AbstractModel) solo per far funzionare la raccolta (poiché Magento\Framework\Data\Collection::setItemObjectClassrichiede l'estensione del modello Magento\Framework\DataObject). Ed è necessario eseguire la raccolta per poter filtrare nel proprio repository. Ma ancora una volta, nel repository devi 'convertire' il tuo modello (normale) in un modello dati.

Oppure dobbiamo implementarlo come il repository degli ordini, dove getList()restituisce un'istanza di Magento\Sales\Api\Data\OrderSearchResultInterface, ma sott'acqua i risultati della ricerca non sono altro che una raccolta regolare che implementa questa interfaccia. Curiosità: i risultati della ricerca indicano che restituirà una matrice di modelli di dati ( Magento\Sales\Api\Data\OrderInterface[]), ma se si analizza il codice, getItems()verrà eseguito il Magento\Framework\Data\Collection::getItems()quale in cambio restituirà non i modelli di dati, ma i modelli di ordine (come impostato da Magento\Sales\Model\ResourceModel\Order\Collection::_construct()). Questo per quanto riguarda la "composizione oltre l'eredità".

Molte domande su qual è il modo corretto in Magento 2. Ancora una volta, ci sono 100 modi per fare la stessa cosa, ma qual è "The Magento Way"? O sono semplicemente sulla strada sbagliata qui?


2
Fare le domande reali qui +1. Mi piacerebbe davvero una risposta di sviluppo centrale qui
Marius

Credo che il piano sia di eliminare gradualmente le Collezioni. Tuttavia, come hai notato, questo non è quasi neanche vicino e ci sono molte aree che sembrano essere in vari stati di refactoring (avendo l'API stabile come Magento \ Sales \ Api \ Data \ OrderSearchResultInterface, consente a Magento di sostituire ciò che succederà più facilmente sotto il cofano in seguito). Non aiuta che le varie implementazioni di getList non siano ancora capaci di ciò che possiamo fare attualmente con le raccolte. L'incoerenza che hai notato sul reso dichiarato potrebbe essere degna di un problema su Github.
Kristof a Fooman il

Risposte:


16

Le raccolte non sono obsolete ora. Mentre alcuni moduli espongono già API del contratto di servizio, altri espongono ancora solo API modello / raccolta.

Il piano è:

  1. Riflette lo stato corrente con una migliore copertura @api: annota le raccolte astratte e le raccolte specifiche in alcuni moduli con @api
  2. Migliora il framework di persistenza per consentire una facile creazione di contratti di servizio senza affidamento su API basate sull'ereditarietà: raccolte, modelli, modelli di risorse
  3. Deprecare la raccolta astratta per non promuovere le implementazioni basate sulla raccolta dei contratti di servizio
  4. Rilasciare gradualmente le versioni più recenti dei moduli con le API del contratto di assistenza

Quindi le raccolte saranno deprecate ad un certo punto, ma ora sono una delle API di Magento 2.

Per quanto riguarda l'implementazione dei contratti di servizio, - Modelli e collezioni sono l'unico modo conveniente per implementarli in Magento <= 2.1. I contratti di assistenza sono solo interfacce. La loro implementazione non fa parte dell'API pubblica e potrebbe essere modificata in un secondo momento.


1
Grazie per la tua risposta. Qual è il tuo consiglio per gli sviluppatori che creano nuovi moduli? La mia attuale strategia è quella di creare contratti di servizio che (sott'acqua) utilizzino ancora le raccolte perché a) facilita il filtraggio eb) il gestore delle entità è ancora troppo sperimentale / non documentato. Ad un certo punto i meccanismi interni possono essere sostituiti da qualsiasi altra cosa, ma l'interfaccia rimane invariata. Ma se capisco correttamente la tua risposta, per ora è il modo giusto?
Giel Berkers,

Corretta. Ho modificato la mia risposta per riflettere questo.
Anton Kril,

1
Considerando quanto sopra, quale sarebbe il modo corretto di implementare funzionalità che richiedono dati che non possono essere recuperati attraverso contratti di servizio? Ad esempio, se il modulo A richiede tutti gli ordini filtrati per metodo di pagamento.
Stjepan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.