Skip to content

Commit 818cf61

Browse files
Merge forwardport of #11473 to 2.3-develop branch
Applied pull request patch https://github.com/magento/magento2/pull/11473.patch (created by @mariuscris) based on commit(s): 1. 42072dd 2. 9dbe444 3. 49fdfae 4. b6ed2d9 5. 9cd20c0 6. 2adefdf 7. cbda7b8 8. 992b3a1 9. 4e937a3 10. c303e4d 11. cd7dc56 12. 6162464 Fixed GitHub Issues in 2.3-develop branch: - #9413: Cannot remove product_list_toolbar in XML (reported by @joshfortyfour)
2 parents 73522bf + 0d8938c commit 818cf61

File tree

2 files changed

+107
-35
lines changed

2 files changed

+107
-35
lines changed

app/code/Magento/Catalog/Block/Product/ListProduct.php

+103-35
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,20 @@
99
use Magento\Catalog\Api\CategoryRepositoryInterface;
1010
use Magento\Catalog\Block\Product\ProductList\Toolbar;
1111
use Magento\Catalog\Model\Category;
12+
use Magento\Catalog\Model\Config;
13+
use Magento\Catalog\Model\Layer;
14+
use Magento\Catalog\Model\Layer\Resolver;
1215
use Magento\Catalog\Model\Product;
1316
use Magento\Catalog\Model\ResourceModel\Product\Collection;
17+
use Magento\Catalog\Pricing\Price\FinalPrice;
1418
use Magento\Eav\Model\Entity\Collection\AbstractCollection;
19+
use Magento\Framework\App\ActionInterface;
20+
use Magento\Framework\App\Config\Element;
21+
use Magento\Framework\Data\Helper\PostHelper;
1522
use Magento\Framework\DataObject\IdentityInterface;
1623
use Magento\Framework\Exception\NoSuchEntityException;
24+
use Magento\Framework\Pricing\Render;
25+
use Magento\Framework\Url\Helper\Data;
1726

1827
/**
1928
* Product list
@@ -40,17 +49,17 @@ class ListProduct extends AbstractProduct implements IdentityInterface
4049
/**
4150
* Catalog layer
4251
*
43-
* @var \Magento\Catalog\Model\Layer
52+
* @var Layer
4453
*/
4554
protected $_catalogLayer;
4655

4756
/**
48-
* @var \Magento\Framework\Data\Helper\PostHelper
57+
* @var PostHelper
4958
*/
5059
protected $_postDataHelper;
5160

5261
/**
53-
* @var \Magento\Framework\Url\Helper\Data
62+
* @var Data
5463
*/
5564
protected $urlHelper;
5665

@@ -61,18 +70,18 @@ class ListProduct extends AbstractProduct implements IdentityInterface
6170

6271
/**
6372
* @param Context $context
64-
* @param \Magento\Framework\Data\Helper\PostHelper $postDataHelper
65-
* @param \Magento\Catalog\Model\Layer\Resolver $layerResolver
73+
* @param PostHelper $postDataHelper
74+
* @param Resolver $layerResolver
6675
* @param CategoryRepositoryInterface $categoryRepository
67-
* @param \Magento\Framework\Url\Helper\Data $urlHelper
76+
* @param Data $urlHelper
6877
* @param array $data
6978
*/
7079
public function __construct(
71-
\Magento\Catalog\Block\Product\Context $context,
72-
\Magento\Framework\Data\Helper\PostHelper $postDataHelper,
73-
\Magento\Catalog\Model\Layer\Resolver $layerResolver,
80+
Context $context,
81+
PostHelper $postDataHelper,
82+
Resolver $layerResolver,
7483
CategoryRepositoryInterface $categoryRepository,
75-
\Magento\Framework\Url\Helper\Data $urlHelper,
84+
Data $urlHelper,
7685
array $data = []
7786
) {
7887
$this->_catalogLayer = $layerResolver->get();
@@ -113,7 +122,7 @@ protected function _getProductCollection()
113122
/**
114123
* Get catalog layer model
115124
*
116-
* @return \Magento\Catalog\Model\Layer
125+
* @return Layer
117126
*/
118127
public function getLayer()
119128
{
@@ -137,7 +146,35 @@ public function getLoadedProductCollection()
137146
*/
138147
public function getMode()
139148
{
140-
return $this->getChildBlock('toolbar')->getCurrentMode();
149+
if ($this->getChildBlock('toolbar')) {
150+
return $this->getChildBlock('toolbar')->getCurrentMode();
151+
}
152+
153+
return $this->getDefaultListingMode();
154+
}
155+
156+
/**
157+
* Get listing mode for products if toolbar is removed from layout.
158+
* Use the general configuration for product list mode from config path catalog/frontend/list_mode as default value
159+
* or mode data from block declaration from layout.
160+
*
161+
* @return string
162+
*/
163+
private function getDefaultListingMode()
164+
{
165+
// default Toolbar when the toolbar layout is not used
166+
$defaultToolbar = $this->getToolbarBlock();
167+
$availableModes = $defaultToolbar->getModes();
168+
169+
// layout config mode
170+
$mode = $this->getData('mode');
171+
172+
if (!$mode || !isset($availableModes[$mode])) {
173+
// default config mode
174+
$mode = $defaultToolbar->getCurrentMode();
175+
}
176+
177+
return $mode;
141178
}
142179

143180
/**
@@ -148,28 +185,60 @@ public function getMode()
148185
protected function _beforeToHtml()
149186
{
150187
$collection = $this->_getProductCollection();
151-
$this->configureToolbar($this->getToolbarBlock(), $collection);
188+
189+
$this->addToolbarBlock($collection);
190+
152191
$collection->load();
153192

154193
return parent::_beforeToHtml();
155194
}
156195

157196
/**
158-
* Retrieve Toolbar block
197+
* Add toolbar block from product listing layout
198+
*
199+
* @param Collection $collection
200+
*/
201+
private function addToolbarBlock(Collection $collection)
202+
{
203+
$toolbarLayout = $this->getToolbarFromLayout();
204+
205+
if ($toolbarLayout) {
206+
$this->configureToolbar($toolbarLayout, $collection);
207+
}
208+
}
209+
210+
/**
211+
* Retrieve Toolbar block from layout or a default Toolbar
159212
*
160213
* @return Toolbar
161214
*/
162215
public function getToolbarBlock()
216+
{
217+
$block = $this->getToolbarFromLayout();
218+
219+
if (!$block) {
220+
$block = $this->getLayout()->createBlock($this->_defaultToolbarBlock, uniqid(microtime()));
221+
}
222+
223+
return $block;
224+
}
225+
226+
/**
227+
* Get toolbar block from layout
228+
*
229+
* @return bool|Toolbar
230+
*/
231+
private function getToolbarFromLayout()
163232
{
164233
$blockName = $this->getToolbarBlockName();
234+
235+
$toolbarLayout = false;
236+
165237
if ($blockName) {
166-
$block = $this->getLayout()->getBlock($blockName);
167-
if ($block) {
168-
return $block;
169-
}
238+
$toolbarLayout = $this->getLayout()->getBlock($blockName);
170239
}
171-
$block = $this->getLayout()->createBlock($this->_defaultToolbarBlock, uniqid(microtime()));
172-
return $block;
240+
241+
return $toolbarLayout;
173242
}
174243

175244
/**
@@ -203,7 +272,7 @@ public function setCollection($collection)
203272
}
204273

205274
/**
206-
* @param array|string|integer|\Magento\Framework\App\Config\Element $code
275+
* @param array|string|integer| Element $code
207276
* @return $this
208277
*/
209278
public function addAttribute($code)
@@ -223,7 +292,7 @@ public function getPriceBlockTemplate()
223292
/**
224293
* Retrieve Catalog Config object
225294
*
226-
* @return \Magento\Catalog\Model\Config
295+
* @return Config
227296
*/
228297
protected function _getConfig()
229298
{
@@ -233,8 +302,8 @@ protected function _getConfig()
233302
/**
234303
* Prepare Sort By fields from Category Data
235304
*
236-
* @param \Magento\Catalog\Model\Category $category
237-
* @return \Magento\Catalog\Block\Product\ListProduct
305+
* @param Category $category
306+
* @return $this
238307
*/
239308
public function prepareSortableFieldsByCategory($category)
240309
{
@@ -286,38 +355,38 @@ public function getIdentities()
286355
/**
287356
* Get post parameters
288357
*
289-
* @param \Magento\Catalog\Model\Product $product
358+
* @param Product $product
290359
* @return string
291360
*/
292-
public function getAddToCartPostParams(\Magento\Catalog\Model\Product $product)
361+
public function getAddToCartPostParams(Product $product)
293362
{
294363
$url = $this->getAddToCartUrl($product);
295364
return [
296365
'action' => $url,
297366
'data' => [
298367
'product' => $product->getEntityId(),
299-
\Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED => $this->urlHelper->getEncodedUrl($url),
368+
ActionInterface::PARAM_NAME_URL_ENCODED => $this->urlHelper->getEncodedUrl($url),
300369
]
301370
];
302371
}
303372

304373
/**
305-
* @param \Magento\Catalog\Model\Product $product
374+
* @param Product $product
306375
* @return string
307376
*/
308-
public function getProductPrice(\Magento\Catalog\Model\Product $product)
377+
public function getProductPrice(Product $product)
309378
{
310379
$priceRender = $this->getPriceRender();
311380

312381
$price = '';
313382
if ($priceRender) {
314383
$price = $priceRender->render(
315-
\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE,
384+
FinalPrice::PRICE_CODE,
316385
$product,
317386
[
318387
'include_container' => true,
319388
'display_minimal_price' => true,
320-
'zone' => \Magento\Framework\Pricing\Render::ZONE_ITEM_LIST,
389+
'zone' => Render::ZONE_ITEM_LIST,
321390
'list_category_page' => true
322391
]
323392
);
@@ -330,7 +399,7 @@ public function getProductPrice(\Magento\Catalog\Model\Product $product)
330399
* Specifies that price rendering should be done for the list of products
331400
* i.e. rendering happens in the scope of product list, but not single product
332401
*
333-
* @return \Magento\Framework\Pricing\Render
402+
* @return Render
334403
*/
335404
protected function getPriceRender()
336405
{
@@ -356,7 +425,7 @@ protected function getPriceRender()
356425
private function initializeProductCollection()
357426
{
358427
$layer = $this->getLayer();
359-
/* @var $layer \Magento\Catalog\Model\Layer */
428+
/* @var $layer Layer */
360429
if ($this->getShowRootCategory()) {
361430
$this->setCategoryId($this->_storeManager->getStore()->getRootCategoryId());
362431
}
@@ -395,8 +464,7 @@ private function initializeProductCollection()
395464
$layer->setCurrentCategory($origCategory);
396465
}
397466

398-
$toolbar = $this->getToolbarBlock();
399-
$this->configureToolbar($toolbar, $collection);
467+
$this->addToolbarBlock($collection);
400468

401469
$this->_eventManager->dispatch(
402470
'catalog_block_product_list_collection',

dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ListTest.php

+4
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ public function testToolbarCoverage()
5555
$parent = $this->_getLayout()->createBlock(\Magento\Catalog\Block\Product\ListProduct::class, 'parent');
5656

5757
/* Prepare toolbar block */
58+
$this->_getLayout()
59+
->createBlock(\Magento\Catalog\Block\Product\ProductList\Toolbar::class, 'product_list_toolbar');
60+
$parent->setToolbarBlockName('product_list_toolbar');
61+
5862
$toolbar = $parent->getToolbarBlock();
5963
$this->assertInstanceOf(\Magento\Catalog\Block\Product\ProductList\Toolbar::class, $toolbar, 'Default Toolbar');
6064

0 commit comments

Comments
 (0)