Magento2: store_id no componente de listagem da interface do usuário


8

Estou desenvolvendo uma extensão Magento2 que possui uma grade administrativa que é gerada usando o UI Listing Component. A grade mostra os registros (uma lista de itens do blog) muito bem. A extensão permite salvar itens do blog para visualizações específicas da loja, o que salva o blog_id junto com o store_id em uma tabela de banco de dados separada. Agora, o que eu gostaria de fazer é mostrar uma coluna na grade com itens do blog que mostra as visualizações da loja selecionadas para cada item do blog.

Toda a configuração é bastante semelhante às páginas do CMS e ao cms_page_listing.xml. Há uma coluna no meu blog_listing.xml para a visualização da loja assim:

<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>

Ao carregar a grade, o seguinte erro é mostrado: " Aviso: índice indefinido: store_id em .. \ vendor \ magento \ module-store \ Ui \ Component \ Listing \ Column \ Store.php na linha 82 "

Obviamente, não há store_id na coleção padrão dos itens do blog, pois ele é conectado através de outra tabela aos store_id reais. Mas minha coleção se parece com isso e deve estar lá: 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');
}

Portanto, minha pergunta é: como vou daqui para que a coluna store_id possa ser renderizada com as visualizações de loja corretas?


Mostre seu código de classe de coleção.
Sohel Rana

O módulo é muito semelhante ao módulo de páginas do CMS. Copiei uma função de \ app \ code \ vendor \ module \ Model \ ResourceModel \ AbstractCollection.php que, acredito, recupera a coleção da grade, incluindo o store_id. Eu sou meio noob, por isso posso estar errado.
Solide 17/04

A coleção pode manipular uma tabela (por padrão). Se você precisar ingressar em outra tabela, precisará trabalhar com '_afterLoad', '_renderFiltersBefore' e finalmente adicionar um mapa.
Sohel Rana

Ok, eu já tenho o _afterload e o _renderFiltersBefore (eu editei a pergunta). Não tenho certeza se eu já adicionei um mapa, você poderia esclarecer isso? Agradeço antecipadamente.
Solide

@Solide, você resolveu esse problema?
Prashant Valanda

Respostas:


1

Finalmente resolvi esse problema. Acontece que eu tinha duas coleções disponíveis para minha grade e a que foi carregada não continha o índice store_id. Para obter mais informações sobre as coleções duplas, consulte: Magento 2: Por que um componente de listagem da interface do usuário precisa de duas coleções?

Para resolver isso, editei a configuração de injeção de dependência em /app/code/vendor/module/etc/di.xml

Aqui eu substituí isso:

<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>

com isso:

<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>

Isso garante que minha coleção de app \ code \ vendor \ module \ Model \ ResourceModel \ AbstractCollection.php seja usada para a grade e agora o store_id com a visualização da loja funcione.


Olá @ Solide, Por favor, responda se qualquer ideia: magento.stackexchange.com/questions/268344/...
akgola
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.