Error en la página del producto cuando tiene productos relacionados y la caché de página completa está activada

16

Recibo este error en algunos productos que tienen productos relacionados:

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

Este problema solo ocurre cuando la caché de página completa está activada . Desafortunadamente, deshabilitarlo no es una opción, ya que la diferencia de velocidad es enorme (más de 2 segundos más rápido con el caché de página).

Intenté todo lo que sé: eliminar nuestro tema, módulos personalizados, etc.

Medio ambiente: producción, 2.1.0, barniz.

Este es el seguimiento completo de la pila:

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";}

¿Alguna idea de dónde buscar?

En la línea 129 en vendor/magento/module-catalog/Block/Product/ProductList/Related.php $this->getItems()es 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;
    } 

¡Gracias!

Claudiu Creanga
fuente
¿Has reescrito Related.php en tu módulo?
Rakesh Jesadiya el
@Rakesh no. solo codició todo. No hay clases relacionadas, excepto el magento y las pruebas
Claudiu Creanga
1
Parece que este error solo ocurre cuando el caché está
activado
1
Entonces, cuando tiene la oportunidad de ver el producto desde un diseño de 2 columnas a un diseño de una sola columna, causa este error
Stevie G
Responda su pregunta si tiene una respuesta
Stevie G

Respuestas:

2

En la misma clase ( vendor/magento/module-catalog/Block/Product/ProductList/Related.php) hay un método como se muestra a continuación. Aquí es donde se establece la colección de elementos y luego se usa en el método getItems () al que está llamando. Depure aquí y confirme que la colección de elementos está obteniendo algunos resultados. Como puede ver, se están aplicando algunos filtros en este código, por lo que existe la posibilidad de que los productos no pasen por esos 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
fuente
1

Simplemente golpee este error en 2.1.7 CE.

Estoy 90% seguro de que esto se debe a que getIdentities () se llama "a menudo" antes de _beforeToHtml (). Esto significa que _prepareData () nunca se llama, por lo que _itemCollection está vacío. Esto tiene un poco de sentido porque el caché quiere saber qué es lo que antes genera el html (y como se señaló getIdentites () está relacionado con el caché).

Entonces getIdentities necesita llamar a _prepareData ()

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

y _prepareData () necesita defenderse de ejecutarse dos veces.

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

Entonces todo está bien.

Editar: Acabo de encontrar este informe de error cerrado https://github.com/magento/magento2/issues/5897 Debería corregirse en futuras versiones.

Chris Lingwood
fuente
0

Lo que podría intentar es agregar lo siguiente a su archivo de diseño de plantilla donde se define este bloque de diseño:

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

Agréguelo a la parte superior del bloque de esta manera:

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

El código anterior significa que no está almacenando en caché este bloque de diseño.

Si esto funciona, significa que el almacenamiento en caché no le permitirá conservar los datos o que algo más lo sobrescribirá y lo dejará vacío. (adivinando aquí)

Myron
fuente
-4

prueba 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
fuente
esto es magento1
Claudiu Creanga
-6

Nos encontramos con este problema. Compruebe si el producto (no los productos relacionados) está agotado. Poner el producto en stock nos resolvió el problema.

cooljoe
fuente
Sin embargo, esto no resuelve el problema, lo evita
Stevie G
Esto no es una solución
harri