Błąd na stronie produktu, gdy masz powiązane produkty i włączona jest pełna pamięć podręczna strony

16

Ten błąd pojawia się w przypadku niektórych produktów, które mają powiązane produkty:

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

Ten problem występuje tylko wtedy, gdy włączona jest pamięć podręczna pełnej strony . Niestety wyłączenie tej opcji nie jest możliwe, ponieważ różnica prędkości jest ogromna (ponad 2 sekundy szybciej z pamięcią podręczną strony).

Próbowałem wszystkiego, co wiem: usuwając nasz motyw, niestandardowe moduły itp.

Środowisko: produkcja, 2.1.0, lakier.

To jest ślad pełnego stosu:

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

Jakieś pomysły, gdzie szukać?

W linii 129 in vendor/magento/module-catalog/Block/Product/ProductList/Related.php $this->getItems()jest null:

  /**
     * 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;
    } 

Dzięki!

Claudiu Creanga
źródło
Czy przepisałeś Related.php w swoim module?
Rakesh Jesadiya
@Rakesh no. po prostu grect wszystko. Brak pokrewnej klasy oprócz magento i testów.
Claudiu Creanga,
1
Wygląda na to, że ten błąd występuje tylko przy włączonej pamięci podręcznej
Stevie G,
1
Więc kiedy masz szansę na widok produktu z układu 2 kolumnowego na układ jednokolumnowy, powoduje to błąd
Stevie G
Jeśli masz odpowiedź, odpowiedz na swoje pytanie
Stevie G,

Odpowiedzi:

2

W tej samej klasie ( vendor/magento/module-catalog/Block/Product/ProductList/Related.php) jest metoda pokazana poniżej. W tym miejscu ustawiana jest kolekcja elementów, a następnie używana w wywoływanej metodzie getItems (). Debuguj tutaj i potwierdź, że kolekcja przedmiotów uzyskuje pewne wyniki. Jak widać, niektóre filtry są stosowane w tym kodzie, więc istnieje szansa, że ​​produkty nie przechodzą przez te filtry.

/**
     * @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
źródło
1

Po prostu traf ten błąd w 2.1.7 CE.

Jestem w 90% pewien, że dzieje się tak, ponieważ getIdentities () jest „często” wywoływane przed _beforeToHtml (). Oznacza to, że _prepareData () nigdy nie jest wywoływana, więc _itemCollection jest pusty. Ma to trochę sensu, ponieważ pamięć podręczna chce wiedzieć, co jest, zanim wygeneruje HTML (i jak wspomniano getIdentites () jest związany z pamięcią podręczną).

Więc getIdentities musi wywołać _prepareData ()

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

i _prepareData () musi się bronić przed dwukrotnym uruchomieniem.

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

Wtedy wszystko jest w porządku.

Edycja: Właśnie znalazłem ten zamknięty raport o błędach https://github.com/magento/magento2/issues/5897 Powinien zostać naprawiony w przyszłej wersji.

Chris Lingwood
źródło
0

Możesz spróbować dodać do pliku układu szablonu, w którym zdefiniowano ten blok układu:

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

Dodaj go na górze bloku tak:

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

Powyższy kod oznacza, że ​​nie buforujesz tego bloku układu.

Jeśli to zadziała, oznacza to, że buforowanie nie pozwoli Ci zachować danych lub zostanie nadpisane przez coś innego, co spowoduje, że będą puste? (zgaduję tutaj)

Myron
źródło
-4

spróbuj tego kodu:

$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
źródło
to jest magento1
Claudiu Creanga
-6

Wpadliśmy na ten problem. Sprawdź, czy produkt (nie produkty powiązane) jest niedostępny. Umieszczenie produktu w magazynie rozwiązało dla nas problem.

Cooljoe
źródło
To jednak nie rozwiązuje problemu, pozwala uniknąć problemu
Stevie G
To nie jest rozwiązanie
harri