Magento2: store_id dans le composant de liste d'interface utilisateur

8

Je développe une extension Magento2 qui a une grille d'administration qui est générée à l'aide du composant de liste d'interface utilisateur. La grille affiche très bien les enregistrements (une liste d'articles de blog). L'extension permet d'enregistrer des éléments de blog pour des vues de magasin spécifiques, ce qui enregistre le blog_id avec le store_id dans une table de base de données distincte. Maintenant, ce que je voudrais faire, c'est afficher une colonne dans la grille avec des articles de blog qui montre les vues du magasin sélectionnées pour chaque article de blog.

L'ensemble de la configuration est assez similaire aux pages CMS et cms_page_listing.xml. Il y a une colonne dans mon blog_listing.xml pour la vue du magasin comme ceci:

<column name="store_id" class="Magento\Store\Ui\Component\Listing\Column\Store">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>
            <item name="sortable" xsi:type="boolean">false</item>
            <item name="label" xsi:type="string" translate="true">Store View</item>
        </item>
    </argument>
</column>

Lors du chargement de la grille, l'erreur suivante s'affiche: " Remarque: index non défini: store_id dans .. \ vendor \ magento \ module-store \ Ui \ Component \ Listing \ Column \ Store.php sur la ligne 82 "

Évidemment, il n'y a pas de store_id dans la collection par défaut des articles de blog car il est connecté via une autre table avec les store_id réels. Mais ma collection ressemble à ceci et elle devrait y être: app \ code \ vendor \ module \ Model \ ResourceModel \ AbstractCollection.php

protected function performAfterLoadBlog($tableName, $columnName) {
    $items = $this->getColumnValues($columnName);
    if (count($items)) {
        $connection = $this->getConnection();
        $select = $connection->select()->from(['blog_entity_store' => $this->getTable($tableName)])
            ->where('blog_entity_store.' . $columnName . ' IN (?)', $items);
        $result = $connection->fetchPairs($select);
        if ($result) {
            foreach ($this as $item) {
                $entityId = $item->getData($columnName);
                if (!isset($result[$entityId])) {
                    continue;
                }
                if ($result[$entityId] == 0) {
                    $stores = $this->storeManager->getStores(false, true);
                    $storeId = current($stores)->getId();
                    $storeCode = key($stores);
                } else {
                    $storeId = $result[$item->getData($columnName)];
                    $storeCode = $this->storeManager->getStore($storeId)->getCode();
                }
                $item->setData('_first_store_id', $storeId);
                $item->setData('store_code', $storeCode);
                $item->setData('store_id', [$result[$entityId]]);
            }
        }
    }
}

protected function joinStoreRelationTable($tableName, $columnName) {
        if ($this->getFilter('store')) {
            $this->getSelect()->join(
                ['store_table' => $this->getTable($tableName)],
                'main_table.' . $columnName . ' = store_table.' . $columnName,
                []
            )->group(
                'main_table.' . $columnName
            );
        }
        parent::_renderFiltersBefore();
    }

\ app \ code \ vendor \ module \ Model \ ResourceModel \ Blog \ Collection.php

protected function _afterLoad()  {
    $this->performAfterLoadBlog('vendor_module_store', 'blog_id');
    $this->_previewFlag = false;

    return parent::_afterLoad();
}

protected function _renderFiltersBefore() {
    $this->joinStoreRelationTable('vendor_module_store', 'blog_id');
}

Donc ma question est, comment puis-je aller à partir d'ici pour que la colonne store_id puisse être rendue avec les vues de magasin correctes?

Solide
la source
Montrez votre code de classe de collection.
Sohel Rana
Le module est très similaire au module des pages CMS. J'ai copié une fonction de \ app \ code \ vendor \ module \ Model \ ResourceModel \ AbstractCollection.php qui, je crois, récupère la collection pour la grille, y compris le store_id. Je suis en quelque sorte un noob, donc je peux me tromper.
Solide
La collection peut gérer une table (par défaut). Si vous devez rejoindre une autre table, vous devez travailler avec '_afterLoad', '_renderFiltersBefore' et enfin ajouter une carte.
Sohel Rana
Ok, j'ai déjà reçu le _afterload et le _renderFiltersBefore (j'ai édité la question). Je ne sais pas si j'ai déjà ajouté une carte, pourriez-vous clarifier cela? Merci d'avance.
Solide
@Solide avez-vous résolu ce problème?
Prashant Valanda

Réponses:

1

Enfin, j'ai résolu ce problème. Il s'est avéré que j'avais deux collections disponibles pour ma grille et celle qui était chargée ne contenait pas l'index store_id. Pour plus d'informations sur les doubles collections, voir: Magento 2: Pourquoi un composant de liste d'interface utilisateur a-t-il besoin de deux collections?

Pour résoudre ce problème, j'ai modifié la configuration de l'injection de dépendance dans /app/code/vendor/module/etc/di.xml

Ici, j'ai remplacé ceci:

<virtualType name="Vendor\Module\Model\ResourceModel\Blog\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
<arguments>
    <argument name="mainTable" xsi:type="string">vendor_module_blog</argument>
    <argument name="resourceModel" xsi:type="string">Vendor\Module\Model\ResourceModel\Blog</argument>
</arguments>

avec ça:

<type name="Vendor\Module\Model\ResourceModel\Blog\Grid\Collection">
<arguments>
    <argument name="mainTable" xsi:type="string">vendor_module_blog</argument>
    <argument name="eventPrefix" xsi:type="string">module_blog_grid_collection</argument>
    <argument name="eventObject" xsi:type="string">module_grid_collection</argument>
    <argument name="resourceModel" xsi:type="string">Vendor\Module\Model\ResourceModel\Blog</argument>
</arguments>

Cela garantit que ma collection de app \ code \ vendor \ module \ Model \ ResourceModel \ AbstractCollection.php est utilisée pour la grille et maintenant le store_id avec la vue de magasin fonctionne.

Solide
la source
Bonjour @ Solide, veuillez répondre si vous avez
akgola