Erro na página do produto quando você tem produtos relacionados e o cache de página inteira está ativado

16

Eu recebo esse erro em alguns produtos que possuem produtos relacionados:

Warning: Invalid argument supplied for foreach() in vendor/magento/module-catalog/Block/Product/ProductList/Related.php on line 129

Esse problema ocorre apenas quando o cache de página inteira está ativado . Infelizmente, desativá-lo não é uma opção, pois a diferença de velocidade é enorme (mais de 2 segundos mais rápido com o cache da página).

Eu tentei tudo o que sei: removendo nosso tema, módulos personalizados etc.

Ambiente: produção, 2.1.0, verniz.

Este é o rastreamento de pilha completo:

a:4:{i:0;s:190:"Warning: Invalid argument supplied for foreach() in vendor/magento/module-catalog/Block/Product/ProductList/Related.php on line 129";i:1;s:5441:"#0 vendor/magento/module-catalog/Block/Product/ProductList/Related.php(129): Magento\Framework\App\ErrorHandler->handler(2, 'Invalid argumen...', '/home/11396-492...', 129, Array)
#1 var/generation/Magento/Catalog/Block/Product/ProductList/Related/Interceptor.php(37): Magento\Catalog\Block\Product\ProductList\Related->getIdentities()
#2 vendor/magento/module-page-cache/Model/Layout/LayoutPlugin.php(71): Magento\Catalog\Block\Product\ProductList\Related\Interceptor->getIdentities()
#3 vendor/magento/framework/Interception/Interceptor.php(152): Magento\PageCache\Model\Layout\LayoutPlugin->afterGetOutput(Object(Magento\Framework\View\Layout\Interceptor), '    <script>\n  ...')
#4 var/generation/Magento/Framework/View/Layout/Interceptor.php(494): Magento\Framework\View\Layout\Interceptor->___callPlugins('getOutput', Array, Array)
#5 vendor/magento/framework/View/Result/Page.php(243): Magento\Framework\View\Layout\Interceptor->getOutput()
#6 vendor/magento/framework/View/Result/Layout.php(164): Magento\Framework\View\Result\Page->render(Object(Magento\Framework\App\Response\Http\Interceptor))
#7 vendor/magento/framework/Interception/Interceptor.php(74): Magento\Framework\View\Result\Layout->renderResult(Object(Magento\Framework\App\Response\Http\Interceptor))
#8 vendor/magento/framework/Interception/Chain/Chain.php(70): Magento\Framework\View\Result\Page\Interceptor->___callParent('renderResult', Array)
#9 vendor/magento/framework/Interception/Chain/Chain.php(63): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Framewo...', 'renderResult', Object(Magento\Framework\View\Result\Page\Interceptor), Array, 'result-varnish-...')
#10 vendor/magento/module-page-cache/Model/Controller/Result/VarnishPlugin.php(74): Magento\Framework\Interception\Chain\Chain->Magento\Framework\Interception\Chain\{closure}(Object(Magento\Framework\App\Response\Http\Interceptor))
#11 vendor/magento/framework/Interception/Chain/Chain.php(67): Magento\PageCache\Model\Controller\Result\VarnishPlugin->aroundRenderResult(Object(Magento\Framework\View\Result\Page\Interceptor), Object(Closure), Object(Magento\Framework\App\Response\Http\Interceptor))
#12 vendor/magento/framework/Interception/Chain/Chain.php(63): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Framewo...', 'renderResult', Object(Magento\Framework\View\Result\Page\Interceptor), Array, 'result-builtin-...')
#13 vendor/magento/module-page-cache/Model/Controller/Result/BuiltinPlugin.php(67): Magento\Framework\Interception\Chain\Chain->Magento\Framework\Interception\Chain\{closure}(Object(Magento\Framework\App\Response\Http\Interceptor))
#14 vendor/magento/framework/Interception/Chain/Chain.php(67): Magento\PageCache\Model\Controller\Result\BuiltinPlugin->aroundRenderResult(Object(Magento\Framework\View\Result\Page\Interceptor), Object(Closure), Object(Magento\Framework\App\Response\Http\Interceptor))
#15 vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Framewo...', 'renderResult', Object(Magento\Framework\View\Result\Page\Interceptor), Array, 'aw_layerednav_r...')
#16 app/code/Aheadworks/Layerednav/Model/Plugin/Result.php(75): Magento\Framework\View\Result\Page\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Response\Http\Interceptor))
#17 vendor/magento/framework/Interception/Interceptor.php(142): Aheadworks\Layerednav\Model\Plugin\Result->aroundRenderResult(Object(Magento\Framework\View\Result\Page\Interceptor), Object(Closure), Object(Magento\Framework\App\Response\Http\Interceptor))
#18 var/generation/Magento/Framework/View/Result/Page/Interceptor.php(130): Magento\Framework\View\Result\Page\Interceptor->___callPlugins('renderResult', Array, Array)
#19 vendor/magento/framework/App/Http.php(139): Magento\Framework\View\Result\Page\Interceptor->renderResult(Object(Magento\Framework\App\Response\Http\Interceptor))
#20 vendor/magento/framework/App/Bootstrap.php(258): Magento\Framework\App\Http->launch()
#21 index.php(39): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http))
#22 {main}";s:3:"url";s:15:"/pecan-pie.html";s:11:"script_name";s:10:"/index.php";}

Alguma idéia para onde procurar?

Na linha 129 em vendor/magento/module-catalog/Block/Product/ProductList/Related.php $this->getItems()é nulo:

  /**
     * Return identifiers for produced content
     *
     * @return array
     */
    public function getIdentities()
    {
        $identities = [];
        var_dump($this->getItems());
        foreach ($this->getItems() as $item) {
            $identities = array_merge($identities, $item->getIdentities());
        }
        return $identities;
    } 

Obrigado!

Claudiu Creanga
fonte
Você reescreve o Related.php no seu módulo?
Rakesh Jesadiya
@Rakesh no. apenas ganhei tudo. Nenhuma classe relacionada, exceto a magento e testes.
Claudiu Creanga
1
Parece que esse erro ocorre apenas quando o cache está
ativado #
1
Então, quando você chance o ponto de vista do produto a partir de um layout 2 coluna para uma única coluna do layout faz com que este erro
Stevie G
Por favor, responda sua pergunta se você tiver uma resposta #
Stevie G

Respostas:

2

Na mesma classe ( vendor/magento/module-catalog/Block/Product/ProductList/Related.php) existe um método como mostrado abaixo. É aqui que a coleção de itens é definida e usada no método getItems () que você está chamando. Depure aqui e confirme se a coleção de itens está obtendo alguns resultados. Como você pode ver, alguns filtros estão sendo aplicados neste código, então há uma chance de os produtos não estarem passando por esses filtros.

/**
     * @return $this
     */
    protected function _prepareData()
    {
        $product = $this->_coreRegistry->registry('product');
        /* @var $product \Magento\Catalog\Model\Product */

        $this->_itemCollection = $product->getRelatedProductCollection()->addAttributeToSelect(
            'required_options'
        )->setPositionOrder()->addStoreFilter();

        if ($this->moduleManager->isEnabled('Magento_Checkout')) {
            $this->_addProductAttributesAndPrices($this->_itemCollection);
        }
        $this->_itemCollection->setVisibility($this->_catalogProductVisibility->getVisibleInCatalogIds());

        $this->_itemCollection->load();

        foreach ($this->_itemCollection as $product) {
            $product->setDoNotUseCategoryId(true);
        }

        return $this;
    }
Siju Joseph
fonte
1

Basta acertar este bug no 2.1.7 CE.

Tenho 90% de certeza, porque getIdentities () é "frequentemente" chamado antes de _beforeToHtml (). Isso significa que _prepareData () nunca é chamado, então _itemCollection está vazio. Isso faz um pouco de sentido, porque o cache quer saber o que é o que antes gera o html (e, como observado, getIdentites () está relacionado ao cache).

Portanto, getIdentities precisa chamar _prepareData ()

public function getIdentities()
{
    $this->_prepareData();

e _prepareData () precisa se defender de executar duas vezes.

protected function _prepareData()
{
    if($this->_itemCollection)
        return $this;

Então está tudo bem.

Edit: Acabei de encontrar este relatório de bug fechado https://github.com/magento/magento2/issues/5897 Deve ser corrigido na versão futura.

Chris Lingwood
fonte
0

O que você pode tentar é adicionar o seguinte ao arquivo de layout do modelo em que este bloco de layout está definido:

<action method="unsetData"><key>cache_lifetime</key></action>
<action method="unsetData"><key>cache_tags</key></action>

Adicione-o ao topo do bloco da seguinte forma:

<module_index_index>
     <action method="unsetData"><key>cache_lifetime</key></action>
     <action method="unsetData"><key>cache_tags</key></action>
     // the actions that are defined
</module_index_index>

O código acima significa que você não está armazenando em cache este bloco de layout.

Se isso funcionar, significa que o armazenamento em cache não permitirá que você mantenha os dados ou será substituído por outra coisa que esteja vazia. (adivinhando aqui)

Myron
fonte
-4

tente este código:

$model = Mage::getModel('catalog/product');
$product = $model->load($product_id);

// Get all related product ids of $product.
$allRelatedProductIds = $product->getRelatedProductIds();

foreach ($allRelatedProductIds as $id) {
            $relatedProduct = $model->load($id);

            // get Product's name
            echo $relatedProduct->getName();

            // get product's short description
            echo $relatedProduct->getShortDescription();

            // get Product's Long Description
            echo $relatedProduct->getDescription();

            // get Product's Regular Price
            echo $relatedProduct->getPrice();

            // get Product's Special price
            echo $relatedProduct->getSpecialPrice();

            // get Product's Url
            echo $relatedProduct->getProductUrl();

            // get Product's image Url
            echo $relatedProduct->getImageUrl();

        }
Vibhanshu Sharma
fonte
isso é magento1
Claudiu Creanga
-6

Nós encontramos esse problema. Verifique se o produto (não os produtos relacionados) está fora de estoque. Colocar o produto em estoque resolveu o problema para nós.

cooljoe
fonte
Porém, isso não resolve o problema, evita o problema #
Stevie G
Esta não é uma solução
harri