From 1a857a3e3bba510db6f20ea7e122e19b37f4d3bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Szubert?= <bartlomiejszubert@gmail.com> Date: Fri, 25 Sep 2020 23:31:17 +0200 Subject: [PATCH] Fix #29063 - Create configurations: not all configurable attributes are visible --- .../Model/ConfigurableAttributeHandler.php | 45 ++++-- .../Model/SuggestedAttributeList.php | 15 +- .../Unit/Model/SuggestedAttributeListTest.php | 131 ------------------ .../Ui/DataProvider/Attributes.php | 18 +-- 4 files changed, 47 insertions(+), 162 deletions(-) delete mode 100644 app/code/Magento/ConfigurableProduct/Test/Unit/Model/SuggestedAttributeListTest.php diff --git a/app/code/Magento/ConfigurableProduct/Model/ConfigurableAttributeHandler.php b/app/code/Magento/ConfigurableProduct/Model/ConfigurableAttributeHandler.php index f9f00289de6a6..e906664cc66d3 100644 --- a/app/code/Magento/ConfigurableProduct/Model/ConfigurableAttributeHandler.php +++ b/app/code/Magento/ConfigurableProduct/Model/ConfigurableAttributeHandler.php @@ -3,22 +3,28 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\ConfigurableProduct\Model; +use Magento\Catalog\Model\Product\Type; +use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory; +use Magento\ConfigurableProduct\Model\Product\Type\Configurable; +use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface; +use Zend_Db_Expr; + class ConfigurableAttributeHandler { /** - * Attribute collection factory - * - * @var \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory + * @var CollectionFactory */ protected $collectionFactory; /** - * @param \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory $attributeColFactory + * @param CollectionFactory $attributeColFactory */ public function __construct( - \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory $attributeColFactory + CollectionFactory $attributeColFactory ) { $this->collectionFactory = $attributeColFactory; } @@ -32,7 +38,7 @@ public function getApplicableAttributes() { /** @var $collection \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection */ $collection = $this->collectionFactory->create(); - return $collection->addFieldToFilter( + $collection->addFieldToFilter( 'frontend_input', 'select' )->addFieldToFilter( @@ -40,20 +46,39 @@ public function getApplicableAttributes() 1 )->addFieldToFilter( 'is_global', - \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL + ScopedAttributeInterface::SCOPE_GLOBAL ); + + $types = [ + Type::TYPE_SIMPLE, + Type::TYPE_VIRTUAL, + Configurable::TYPE_CODE, + ]; + $applyToArr = []; + foreach ($types as $type) { + $applyToArr[] = "apply_to REGEXP '(^|(.*,))$type($|,.*)'"; + } + $whereExprStr = 'apply_to IS NULL OR (' . implode(' AND ', $applyToArr) . ')'; + + $collection->getSelect()->where(new Zend_Db_Expr($whereExprStr)); + + return $collection; } /** + * Check if attribute is applicable for configurable products + * @deprecated is applicable check is added to collection query + * @see \Magento\ConfigurableProduct\Model\ConfigurableAttributeHandler::getApplicableAttributes * @param \Magento\Catalog\Api\Data\ProductAttributeInterface $attribute + * * @return bool */ public function isAttributeApplicable($attribute) { $types = [ - \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE, - \Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL, - \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE, + Type::TYPE_SIMPLE, + Type::TYPE_VIRTUAL, + Configurable::TYPE_CODE, ]; return !$attribute->getApplyTo() || count(array_diff($types, $attribute->getApplyTo())) === 0; } diff --git a/app/code/Magento/ConfigurableProduct/Model/SuggestedAttributeList.php b/app/code/Magento/ConfigurableProduct/Model/SuggestedAttributeList.php index d13ba61ef1418..1ace35a49eeb3 100644 --- a/app/code/Magento/ConfigurableProduct/Model/SuggestedAttributeList.php +++ b/app/code/Magento/ConfigurableProduct/Model/SuggestedAttributeList.php @@ -50,15 +50,14 @@ public function getSuggestedAttributes($labelPart) $result = []; foreach ($collection->getItems() as $id => $attribute) { /** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ - if ($this->configurableAttributeHandler->isAttributeApplicable($attribute)) { - $result[$id] = [ - 'id' => $attribute->getId(), - 'label' => $attribute->getFrontendLabel(), - 'code' => $attribute->getAttributeCode(), - 'options' => $attribute->getSource()->getAllOptions(false), - ]; - } + $result[$id] = [ + 'id' => $attribute->getId(), + 'label' => $attribute->getFrontendLabel(), + 'code' => $attribute->getAttributeCode(), + 'options' => $attribute->getSource()->getAllOptions(false), + ]; } + return $result; } } diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/SuggestedAttributeListTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/SuggestedAttributeListTest.php deleted file mode 100644 index 1479c9bc03f18..0000000000000 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/SuggestedAttributeListTest.php +++ /dev/null @@ -1,131 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\ConfigurableProduct\Test\Unit\Model; - -use Magento\Catalog\Model\ResourceModel\Eav\Attribute; -use Magento\Catalog\Model\ResourceModel\Helper; -use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection; -use Magento\ConfigurableProduct\Model\ConfigurableAttributeHandler; -use Magento\ConfigurableProduct\Model\SuggestedAttributeList; -use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource; -use PHPUnit\Framework\MockObject\MockObject; -use PHPUnit\Framework\TestCase; - -class SuggestedAttributeListTest extends TestCase -{ - /** - * @var SuggestedAttributeList - */ - protected $suggestedListModel; - - /** - * @var ConfigurableAttributeHandler|MockObject - */ - protected $configurableAttributeHandler; - - /** - * @var MockObject - */ - protected $resourceHelperMock; - - /** - * @var MockObject - */ - protected $collectionMock; - - /** - * @var MockObject - */ - protected $attributeMock; - - /** - * @var string - */ - protected $labelPart = 'labelPart'; - - protected function setUp(): void - { - $this->configurableAttributeHandler = $this->createMock( - ConfigurableAttributeHandler::class - ); - $this->resourceHelperMock = $this->createMock(Helper::class); - $this->collectionMock = $this->createMock( - Collection::class - ); - $this->resourceHelperMock->expects( - $this->once() - )->method( - 'addLikeEscape' - )->with( - $this->labelPart, - ['position' => 'any'] - )->willReturn( - $this->labelPart - ); - $this->configurableAttributeHandler->expects( - $this->once() - )->method( - 'getApplicableAttributes' - )->willReturn( - $this->collectionMock - ); - $valueMap = [ - ['frontend_label', ['like' => $this->labelPart], $this->collectionMock], - ]; - $this->collectionMock->expects( - $this->any() - )->method( - 'addFieldToFilter' - )->willReturnMap( - $valueMap - ); - $this->attributeMock = $this->getMockBuilder(Attribute::class) - ->addMethods(['getFrontendLabel']) - ->onlyMethods(['getId', 'getAttributeCode', 'getSource']) - ->disableOriginalConstructor() - ->getMock(); - $this->collectionMock->expects( - $this->once() - )->method( - 'getItems' - )->willReturn( - ['id' => $this->attributeMock] - ); - $this->suggestedListModel = new SuggestedAttributeList( - $this->configurableAttributeHandler, - $this->resourceHelperMock - ); - } - - public function testGetSuggestedAttributesIfTheyApplicable() - { - $source = $this->createMock(AbstractSource::class); - $result['id'] = ['id' => 'id', 'label' => 'label', 'code' => 'code', 'options' => 'options']; - $this->attributeMock->expects($this->once())->method('getId')->willReturn('id'); - $this->attributeMock->expects($this->once())->method('getFrontendLabel')->willReturn('label'); - $this->attributeMock->expects($this->once())->method('getAttributeCode')->willReturn('code'); - $this->attributeMock->expects($this->once())->method('getSource')->willReturn($source); - $source->expects($this->once())->method('getAllOptions')->with(false)->willReturn('options'); - $this->configurableAttributeHandler->expects($this->once())->method('isAttributeApplicable') - ->with($this->attributeMock)->willReturn(true); - - $this->assertEquals($result, $this->suggestedListModel->getSuggestedAttributes($this->labelPart)); - } - - public function testGetSuggestedAttributesIfTheyNotApplicable() - { - $this->attributeMock->expects($this->never())->method('getId'); - $this->attributeMock->expects($this->never())->method('getFrontendLabel'); - $this->attributeMock->expects($this->never())->method('getAttributeCode'); - $this->attributeMock->expects($this->never())->method('getSource'); - $this->configurableAttributeHandler->expects($this->once())->method('isAttributeApplicable') - ->with($this->attributeMock)->willReturn(false); - - $this->assertEquals([], $this->suggestedListModel->getSuggestedAttributes($this->labelPart)); - } -} diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Attributes.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Attributes.php index 04db96bc158d1..877433768f434 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Attributes.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Attributes.php @@ -43,22 +43,14 @@ public function getCollection() } /** - * {@inheritdoc} + * @inheritDoc */ public function getData() { - $items = []; - $skippedItems = 0; - foreach ($this->getCollection()->getItems() as $attribute) { - if ($this->configurableAttributeHandler->isAttributeApplicable($attribute)) { - $items[] = $attribute->toArray(); - } else { - $skippedItems++; - } + if (!$this->getCollection()->isLoaded()) { + $this->getCollection()->load(); } - return [ - 'totalRecords' => $this->collection->getSize() - $skippedItems, - 'items' => $items - ]; + + return $this->getCollection()->toArray(); } }