diff --git a/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/BundleDataProviderTest.php b/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/BundleDataProviderTest.php
index 9eb0e7aa8946c..a0fc752304392 100644
--- a/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/BundleDataProviderTest.php
+++ b/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/BundleDataProviderTest.php
@@ -14,6 +14,8 @@
use Magento\Framework\App\RequestInterface;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Store\Model\Store;
+use Magento\Ui\DataProvider\Modifier\ModifierInterface;
+use Magento\Ui\DataProvider\Modifier\PoolInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
@@ -46,6 +48,16 @@ class BundleDataProviderTest extends TestCase
*/
protected $dataHelperMock;
+ /**
+ * @var PoolInterface|MockObject
+ */
+ private $modifiersPool;
+
+ /**
+ * @var ModifierInterface|MockObject
+ */
+ private $modifierMockOne;
+
/**
* @return void
*/
@@ -55,6 +67,8 @@ protected function setUp(): void
$this->requestMock = $this->getMockBuilder(RequestInterface::class)
->getMockForAbstractClass();
+ $this->modifiersPool = $this->getMockBuilder(PoolInterface::class)
+ ->getMockForAbstractClass();
$this->collectionMock = $this->getMockBuilder(Collection::class)
->disableOriginalConstructor()
->setMethods(
@@ -79,6 +93,15 @@ protected function setUp(): void
->disableOriginalConstructor()
->setMethods(['getAllowedSelectionTypes'])
->getMock();
+ $this->modifierMockOne = $this->getMockBuilder(ModifierInterface::class)
+ ->setMethods(['modifyData'])
+ ->getMockForAbstractClass();
+ $this->modifierMockOne->expects($this->any())
+ ->method('modifyData')
+ ->willReturn($this->returnArgument(0));
+ $this->modifiersPool->expects($this->any())
+ ->method('getModifiersInstances')
+ ->willReturn([$this->modifierMockOne]);
}
/**
@@ -97,6 +120,7 @@ protected function getModel()
'addFilterStrategies' => [],
'meta' => [],
'data' => [],
+ 'modifiersPool' => $this->modifiersPool
]);
}
diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/BundleDataProvider.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/BundleDataProvider.php
index 5f1ffc3c26823..476a27745d189 100644
--- a/app/code/Magento/Bundle/Ui/DataProvider/Product/BundleDataProvider.php
+++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/BundleDataProvider.php
@@ -8,6 +8,9 @@
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider;
use Magento\Bundle\Helper\Data;
+use Magento\Ui\DataProvider\Modifier\ModifierInterface;
+use Magento\Ui\DataProvider\Modifier\PoolInterface;
+use Magento\Framework\App\ObjectManager;
class BundleDataProvider extends ProductDataProvider
{
@@ -16,6 +19,11 @@ class BundleDataProvider extends ProductDataProvider
*/
protected $dataHelper;
+ /**
+ * @var PoolInterface
+ */
+ private $modifiersPool;
+
/**
* Construct
*
@@ -24,10 +32,11 @@ class BundleDataProvider extends ProductDataProvider
* @param string $requestFieldName
* @param CollectionFactory $collectionFactory
* @param Data $dataHelper
- * @param \Magento\Ui\DataProvider\AddFieldToCollectionInterface[] $addFieldStrategies
- * @param \Magento\Ui\DataProvider\AddFilterToCollectionInterface[] $addFilterStrategies
* @param array $meta
* @param array $data
+ * @param \Magento\Ui\DataProvider\AddFieldToCollectionInterface[] $addFieldStrategies
+ * @param \Magento\Ui\DataProvider\AddFilterToCollectionInterface[] $addFilterStrategies
+ * @param PoolInterface|null $modifiersPool
*/
public function __construct(
$name,
@@ -38,7 +47,8 @@ public function __construct(
array $meta = [],
array $data = [],
array $addFieldStrategies = [],
- array $addFilterStrategies = []
+ array $addFilterStrategies = [],
+ PoolInterface $modifiersPool = null
) {
parent::__construct(
$name,
@@ -52,6 +62,7 @@ public function __construct(
);
$this->dataHelper = $dataHelper;
+ $this->modifiersPool = $modifiersPool ?: ObjectManager::getInstance()->get(PoolInterface::class);
}
/**
@@ -74,9 +85,16 @@ public function getData()
}
$items = $this->getCollection()->toArray();
- return [
+ $data = [
'totalRecords' => $this->getCollection()->getSize(),
'items' => array_values($items),
];
+
+ /** @var ModifierInterface $modifier */
+ foreach ($this->modifiersPool->getModifiersInstances() as $modifier) {
+ $data = $modifier->modifyData($data);
+ }
+
+ return $data;
}
}
diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php
index 01b113def9243..a1ace93d704e4 100644
--- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php
+++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php
@@ -671,7 +671,7 @@ protected function getBundleSelections()
'componentType' => Form\Field::NAME,
'dataType' => Form\Element\DataType\Text::NAME,
'formElement' => Form\Element\Input::NAME,
- 'elementTmpl' => 'ui/dynamic-rows/cells/text',
+ 'elementTmpl' => 'ui/form/element/html',
'label' => __('Name'),
'dataScope' => 'name',
'sortOrder' => 60,
diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php
index 4abc72f1f3f97..9f6b595d453af 100644
--- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php
+++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php
@@ -12,6 +12,7 @@
use Magento\Bundle\Model\Product\Type;
use Magento\Bundle\Api\ProductOptionRepositoryInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
+use Magento\Catalog\Helper\Product\AddUrlToName as NameHelper;
/**
* Class Bundle customizes Bundle product creation flow
@@ -45,11 +46,17 @@ class Composite extends AbstractModifier
*/
protected $productRepository;
+ /**
+ * @var NameHelper
+ */
+ private $nameHelper;
+
/**
* @param LocatorInterface $locator
* @param ObjectManagerInterface $objectManager
* @param ProductOptionRepositoryInterface $optionsRepository
* @param ProductRepositoryInterface $productRepository
+ * @param NameHelper $nameHelper
* @param array $modifiers
*/
public function __construct(
@@ -57,12 +64,14 @@ public function __construct(
ObjectManagerInterface $objectManager,
ProductOptionRepositoryInterface $optionsRepository,
ProductRepositoryInterface $productRepository,
+ NameHelper $nameHelper,
array $modifiers = []
) {
$this->locator = $locator;
$this->objectManager = $objectManager;
$this->optionsRepository = $optionsRepository;
$this->productRepository = $productRepository;
+ $this->nameHelper = $nameHelper;
$this->modifiers = $modifiers;
}
@@ -115,7 +124,7 @@ public function modifyData(array $data)
'selection_id' => $productLink->getId(),
'option_id' => $productLink->getOptionId(),
'product_id' => $linkedProduct->getId(),
- 'name' => $linkedProduct->getName(),
+ 'name' => $this->nameHelper->addUrlToName($linkedProduct),
'sku' => $linkedProduct->getSku(),
'is_default' => ($productLink->getIsDefault()) ? '1' : '0',
'selection_price_value' => $productLink->getPrice(),
diff --git a/app/code/Magento/Bundle/etc/di.xml b/app/code/Magento/Bundle/etc/di.xml
index c5c4a491234ed..aec6aad6155b3 100644
--- a/app/code/Magento/Bundle/etc/di.xml
+++ b/app/code/Magento/Bundle/etc/di.xml
@@ -290,4 +290,9 @@
+
+
+ Magento\Catalog\Ui\DataProvider\Product\Name\Modifier\Pool
+
+
diff --git a/app/code/Magento/Bundle/view/adminhtml/ui_component/bundle_product_listing.xml b/app/code/Magento/Bundle/view/adminhtml/ui_component/bundle_product_listing.xml
index d69196a61c59d..8925279154106 100644
--- a/app/code/Magento/Bundle/view/adminhtml/ui_component/bundle_product_listing.xml
+++ b/app/code/Magento/Bundle/view/adminhtml/ui_component/bundle_product_listing.xml
@@ -109,6 +109,7 @@
true
text
+ ui/grid/cells/html
@@ -139,5 +140,11 @@
+
+
+ entity_id
+
+
+
diff --git a/app/code/Magento/Catalog/Helper/Product/AddUrlToName.php b/app/code/Magento/Catalog/Helper/Product/AddUrlToName.php
new file mode 100644
index 0000000000000..5b9e671c3e02a
--- /dev/null
+++ b/app/code/Magento/Catalog/Helper/Product/AddUrlToName.php
@@ -0,0 +1,75 @@
+locator = $locator;
+ $this->urlBuilder = $urlBuilder;
+ $this->escaper = $escaper;
+ }
+
+ /**
+ * Add url to product name
+ *
+ * @param ProductInterface $linkedProduct
+ * @return string
+ */
+ public function addUrlToName(ProductInterface $linkedProduct): string
+ {
+ $storeId = $this->locator->getStore()->getId();
+
+ $url = $this->urlBuilder->getUrl(
+ 'catalog/product/edit',
+ [
+ 'id' => $linkedProduct->getId(),
+ 'store' => $storeId
+ ]
+ );
+
+ return ''
+ . $this->escaper->escapeHtml(
+ $linkedProduct->getName()
+ ) . '';
+ }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Helper/Product/AddUrlToNameTest.php b/app/code/Magento/Catalog/Test/Unit/Helper/Product/AddUrlToNameTest.php
new file mode 100644
index 0000000000000..27decb6343ead
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Helper/Product/AddUrlToNameTest.php
@@ -0,0 +1,149 @@
+objectManager = new ObjectManager($this);
+
+ $this->locatorMock = $this->getMockBuilder(LocatorInterface::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getStore'])
+ ->getMockForAbstractClass();
+ $this->urlBuilderMock = $this->getMockBuilder(UrlInterface::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getUrl'])
+ ->getMockForAbstractClass();
+ $this->escaperMock = $this->getMockBuilder(Escaper::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['escapeHtml'])
+ ->getMock();
+ $this->storeMock = $this->getMockBuilder(StoreInterface::class)
+ ->setMethods(['getId'])
+ ->getMockForAbstractClass();
+ $this->linkedProductMock = $this->getMockBuilder(ProductInterface::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getName'])
+ ->getMockForAbstractClass();
+
+ $this->storeMock->expects($this->any())
+ ->method('getId')
+ ->willReturn(1);
+ $this->locatorMock->expects($this->any())
+ ->method('getStore')
+ ->willReturn($this->storeMock);
+ $this->urlBuilderMock->expects($this->any())
+ ->method('getUrl')
+ ->willReturn(self::SAMPLE_PRODUCT_URL);
+ $this->escaperMock->expects($this->any())
+ ->method('escapeHtml')
+ ->willReturn(self::SAMPLE_PRODUCT_NAME);
+ }
+
+ /**
+ * Test checks AddUrlToName type
+ */
+ public function testCheckType(): void
+ {
+ $this->assertInstanceOf(AddUrlToName::class, $this->getModel());
+ }
+
+ /**
+ * Test checks modifyData method
+ *
+ * @param string $expectedData
+ * @dataProvider getDataDataProvider
+ */
+ public function testAddUrlToName(string $expectedData): void
+ {
+ $this->assertSame($expectedData, $this->getModel()->addUrlToName($this->linkedProductMock));
+ }
+
+ /**
+ * @return array
+ */
+ public function getDataDataProvider()
+ {
+ return [
+ 0 => [
+ 'expectedData' =>
+ 'Sample product',
+ ]
+ ];
+ }
+
+ /**
+ * @return object
+ */
+ private function getModel(): AddUrlToName
+ {
+ return $this->objectManager->getObject(AddUrlToName::class, [
+ 'locator' => $this->locatorMock,
+ 'urlBuilder' => $this->urlBuilderMock,
+ 'escaper' => $this->escaperMock,
+ ]);
+ }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/RelatedTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/RelatedTest.php
index ee8d9e8b0cd44..5e2b5cd75c0fb 100644
--- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/RelatedTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/RelatedTest.php
@@ -11,6 +11,7 @@
use Magento\Catalog\Api\ProductLinkRepositoryInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Helper\Image as ImageHelper;
+use Magento\Catalog\Helper\Product\AddUrlToName as NameHelper;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\Catalog\Model\ProductLink\Link;
use Magento\Catalog\Ui\Component\Listing\Columns\Price;
@@ -49,6 +50,11 @@ class RelatedTest extends AbstractModifierTest
*/
private $attributeSetRepository;
+ /**
+ * @var NameHelper|MockObject
+ */
+ private $nameHelper;
+
/**
* @inheritdoc
*/
@@ -60,6 +66,7 @@ protected function setUp(): void
$this->imageHelper = $this->createMock(ImageHelper::class);
$this->status = $this->createMock(Status::class);
$this->attributeSetRepository = $this->createMock(AttributeSetRepositoryInterface::class);
+ $this->nameHelper = $this->createMock(NameHelper::class);
}
/**
@@ -74,6 +81,7 @@ protected function createModel()
'imageHelper' => $this->imageHelper,
'status' => $this->status,
'attributeSetRepository' => $this->attributeSetRepository,
+ 'nameHelper' => $this->nameHelper
]);
}
@@ -104,6 +112,7 @@ public function testSorting(array $productLinks, array $expectedLinks): void
$currentProductId = 1;
$currentStoreId = 1;
$thumnailUrl = '/path/to/thumnail';
+ $productName = 'Simple product';
$model = $this->getModel();
$priceModifier = $this->createMock(Price::class);
$attributeSet = $this->createConfiguredMock(AttributeSetInterface::class, ['getAttributeSetName' => 'Default']);
@@ -141,6 +150,8 @@ function (array $linkData) {
$productLinks
)
);
+ $this->nameHelper->method('addUrlToName')
+ ->willReturn($productName);
$data = $this->getSampleData();
$expected = $data;
$expected[$currentProductId]['links'] = $expectedLinks;
@@ -164,7 +175,7 @@ private function getProducts(): array
$product = $this->createMock(ProductInterface::class);
$product->method('getId')->willReturn($n);
$product->method('getSku')->willReturn($sku);
- $product->method('getName')->willReturn('Simple ' . $n);
+ $product->method('getName')->willReturn('Simple product');
$product->method('getPrice')->willReturn($n % 10);
$products[$sku] = $product;
} while (++$n < 20);
@@ -231,7 +242,7 @@ public function sortingDataProvider(): array
[
'id' => 2,
'thumbnail' => '/path/to/thumnail',
- 'name' => 'Simple 2',
+ 'name' => 'Simple product',
'status' => 'Enabled',
'attribute_set' => 'Default',
'sku' => 'simple-2',
@@ -241,7 +252,7 @@ public function sortingDataProvider(): array
[
'id' => 3,
'thumbnail' => '/path/to/thumnail',
- 'name' => 'Simple 3',
+ 'name' => 'Simple product',
'status' => 'Enabled',
'attribute_set' => 'Default',
'sku' => 'simple-3',
@@ -251,7 +262,7 @@ public function sortingDataProvider(): array
[
'id' => 13,
'thumbnail' => '/path/to/thumnail',
- 'name' => 'Simple 13',
+ 'name' => 'Simple product',
'status' => 'Enabled',
'attribute_set' => 'Default',
'sku' => 'simple-13',
@@ -263,7 +274,7 @@ public function sortingDataProvider(): array
[
'id' => 11,
'thumbnail' => '/path/to/thumnail',
- 'name' => 'Simple 11',
+ 'name' => 'Simple product',
'status' => 'Enabled',
'attribute_set' => 'Default',
'sku' => 'simple-11',
@@ -273,7 +284,7 @@ public function sortingDataProvider(): array
[
'id' => 17,
'thumbnail' => '/path/to/thumnail',
- 'name' => 'Simple 17',
+ 'name' => 'Simple product',
'status' => 'Enabled',
'attribute_set' => 'Default',
'sku' => 'simple-17',
@@ -283,7 +294,7 @@ public function sortingDataProvider(): array
[
'id' => 6,
'thumbnail' => '/path/to/thumnail',
- 'name' => 'Simple 6',
+ 'name' => 'Simple product',
'status' => 'Enabled',
'attribute_set' => 'Default',
'sku' => 'simple-6',
@@ -295,7 +306,7 @@ public function sortingDataProvider(): array
[
'id' => 9,
'thumbnail' => '/path/to/thumnail',
- 'name' => 'Simple 9',
+ 'name' => 'Simple product',
'status' => 'Enabled',
'attribute_set' => 'Default',
'sku' => 'simple-9',
@@ -305,7 +316,7 @@ public function sortingDataProvider(): array
[
'id' => 19,
'thumbnail' => '/path/to/thumnail',
- 'name' => 'Simple 19',
+ 'name' => 'Simple product',
'status' => 'Enabled',
'attribute_set' => 'Default',
'sku' => 'simple-19',
@@ -315,7 +326,7 @@ public function sortingDataProvider(): array
[
'id' => 7,
'thumbnail' => '/path/to/thumnail',
- 'name' => 'Simple 7',
+ 'name' => 'Simple product',
'status' => 'Enabled',
'attribute_set' => 'Default',
'sku' => 'simple-7',
diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Modifier/AddUrlToNameTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Modifier/AddUrlToNameTest.php
new file mode 100644
index 0000000000000..3391b2a9b212e
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Modifier/AddUrlToNameTest.php
@@ -0,0 +1,165 @@
+objectManager = new ObjectManager($this);
+
+ $this->urlBuilderMock = $this->getMockBuilder(UrlInterface::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getUrl'])
+ ->getMockForAbstractClass();
+ $this->escaperMock = $this->getMockBuilder(Escaper::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['escapeHtml'])
+ ->getMock();
+ $this->requestMock = $this->getMockBuilder(Http::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getStore'])
+ ->getMockForAbstractClass();
+ $this->storeMock = $this->getMockBuilder(StoreInterface::class)
+ ->setMethods(['getId'])
+ ->getMockForAbstractClass();
+
+ $this->storeMock->expects($this->any())
+ ->method('getId')
+ ->willReturn(1);
+ $this->storeManagerMock->expects($this->any())
+ ->method('getStore')
+ ->willReturn($this->storeMock);
+ $this->urlBuilderMock->expects($this->any())
+ ->method('getUrl')
+ ->willReturn(self::SAMPLE_PRODUCT_URL);
+ $this->escaperMock->expects($this->any())
+ ->method('escapeHtml')
+ ->willReturn(self::SAMPLE_PRODUCT_NAME);
+ }
+
+ /**
+ * Test checks AddUrlToName type
+ */
+ public function testCheckType(): void
+ {
+ $this->assertInstanceOf(AddUrlToName::class, $this->getModel());
+ }
+
+ /**
+ * Test checks modifyData method
+ *
+ * @param array $expectedData
+ * @param array $providedData
+ * @dataProvider getDataDataProvider
+ */
+ public function testModifyData(array $expectedData, array $providedData): void
+ {
+ $this->assertSame($expectedData, $this->getModel()->modifyData($providedData));
+ }
+
+ /**
+ * @return array
+ */
+ public function getDataDataProvider(): array
+ {
+ return [
+ 0 => [
+ 'expectedData' => [
+ 'items' => [
+ [
+ 'entity_id' => '1',
+ 'name' =>
+ 'Sample product'
+ ]
+ ]
+ ],
+ 'providedData' => [
+ 'items' => [
+ [
+ 'entity_id' => '1',
+ 'name' => 'Sample product'
+ ]
+ ]
+ ]
+ ]
+ ];
+ }
+
+ /**
+ * @return object
+ */
+ private function getModel(): AddUrlToName
+ {
+ return $this->objectManager->getObject(AddUrlToName::class, [
+ 'urlBuilder' => $this->urlBuilderMock,
+ 'escaper' => $this->escaperMock,
+ 'request' => $this->requestMock,
+ 'storeManager' => $this->storeManagerMock,
+ ]);
+ }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/ProductCustomOptionsDataProviderTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/ProductCustomOptionsDataProviderTest.php
index 33c68b83a91d9..067818428cef8 100644
--- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/ProductCustomOptionsDataProviderTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/ProductCustomOptionsDataProviderTest.php
@@ -15,6 +15,7 @@
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+use Magento\Ui\DataProvider\Modifier\ModifierInterface;
use Magento\Ui\DataProvider\Modifier\PoolInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
@@ -66,6 +67,11 @@ class ProductCustomOptionsDataProviderTest extends TestCase
*/
private $modifiersPool;
+ /**
+ * @var ModifierInterface|MockObject
+ */
+ private $modifierMockOne;
+
protected function setUp(): void
{
$this->collectionFactoryMock = $this->getMockBuilder(CollectionFactory::class)
@@ -120,6 +126,17 @@ protected function setUp(): void
'metadataPool' => $this->metadataPool
]
);
+
+ $this->modifierMockOne = $this->getMockBuilder(ModifierInterface::class)
+ ->setMethods(['modifyData'])
+ ->getMockForAbstractClass();
+ $this->modifierMockOne->expects($this->any())
+ ->method('modifyData')
+ ->willReturn($this->returnArgument(0));
+
+ $this->modifiersPool->expects($this->any())
+ ->method('getModifiersInstances')
+ ->willReturn([$this->modifierMockOne]);
}
/**
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Related.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Related.php
index e026890c4c3f3..10903c0f8bee1 100644
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Related.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Related.php
@@ -10,8 +10,8 @@
use Magento\Catalog\Api\ProductLinkRepositoryInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Locator\LocatorInterface;
+use Magento\Catalog\Helper\Product\AddUrlToName as NameHelper;
use Magento\Eav\Api\AttributeSetRepositoryInterface;
-use Magento\Framework\App\ObjectManager;
use Magento\Framework\Phrase;
use Magento\Framework\UrlInterface;
use Magento\Ui\Component\DynamicRows;
@@ -23,6 +23,7 @@
use Magento\Ui\Component\Modal;
use Magento\Catalog\Helper\Image as ImageHelper;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
+use Magento\Catalog\Ui\Component\Listing\Columns\Price;
/**
* Class for Product Modifier Related
@@ -98,6 +99,11 @@ class Related extends AbstractModifier
*/
protected $scopeName;
+ /**
+ * @var NameHelper
+ */
+ private $nameHelper;
+
/**
* @var string
* @since 101.0.0
@@ -105,7 +111,7 @@ class Related extends AbstractModifier
protected $scopePrefix;
/**
- * @var \Magento\Catalog\Ui\Component\Listing\Columns\Price
+ * @var Price
*/
private $priceModifier;
@@ -117,6 +123,8 @@ class Related extends AbstractModifier
* @param ImageHelper $imageHelper
* @param Status $status
* @param AttributeSetRepositoryInterface $attributeSetRepository
+ * @param NameHelper $nameHelper
+ * @param Price $priceModifier
* @param string $scopeName
* @param string $scopePrefix
*/
@@ -128,6 +136,8 @@ public function __construct(
ImageHelper $imageHelper,
Status $status,
AttributeSetRepositoryInterface $attributeSetRepository,
+ NameHelper $nameHelper,
+ Price $priceModifier,
$scopeName = '',
$scopePrefix = ''
) {
@@ -138,6 +148,8 @@ public function __construct(
$this->imageHelper = $imageHelper;
$this->status = $status;
$this->attributeSetRepository = $attributeSetRepository;
+ $this->nameHelper = $nameHelper;
+ $this->priceModifier = $priceModifier;
$this->scopeName = $scopeName;
$this->scopePrefix = $scopePrefix;
}
@@ -248,11 +260,6 @@ public function modifyData(array $data)
*/
private function getPriceModifier()
{
- if (!$this->priceModifier) {
- $this->priceModifier = ObjectManager::getInstance()->get(
- \Magento\Catalog\Ui\Component\Listing\Columns\Price::class
- );
- }
return $this->priceModifier;
}
@@ -269,7 +276,7 @@ protected function fillData(ProductInterface $linkedProduct, ProductLinkInterfac
return [
'id' => $linkedProduct->getId(),
'thumbnail' => $this->imageHelper->init($linkedProduct, 'product_listing_thumbnail')->getUrl(),
- 'name' => $linkedProduct->getName(),
+ 'name' => $this->nameHelper->addUrlToName($linkedProduct),
'status' => $this->status->getOptionText($linkedProduct->getStatus()),
'attribute_set' => $this->attributeSetRepository
->get($linkedProduct->getAttributeSetId())
@@ -644,7 +651,7 @@ protected function fillMeta()
],
],
],
- 'name' => $this->getTextColumn('name', false, __('Name'), 20),
+ 'name' => $this->getHtmlColumn('name', false, __('Name'), 20),
'status' => $this->getTextColumn('status', true, __('Status'), 30),
'attribute_set' => $this->getTextColumn('attribute_set', false, __('Attribute Set'), 40),
'sku' => $this->getTextColumn('sku', true, __('SKU'), 50),
@@ -712,4 +719,36 @@ protected function getTextColumn($dataScope, $fit, Phrase $label, $sortOrder)
return $column;
}
+
+ /**
+ * Retrieve html column structure
+ *
+ * @param string $dataScope
+ * @param bool $fit
+ * @param Phrase $label
+ * @param int $sortOrder
+ * @return array
+ */
+ private function getHtmlColumn($dataScope, $fit, Phrase $label, $sortOrder) : array
+ {
+ $column = [
+ 'arguments' => [
+ 'data' => [
+ 'config' => [
+ 'componentType' => Field::NAME,
+ 'formElement' => Input::NAME,
+ 'elementTmpl' => 'Magento_Catalog/components/cell-html',
+ 'component' => 'Magento_Ui/js/form/element/text',
+ 'dataType' => Text::NAME,
+ 'dataScope' => $dataScope,
+ 'fit' => $fit,
+ 'label' => $label,
+ 'sortOrder' => $sortOrder,
+ ],
+ ],
+ ],
+ ];
+
+ return $column;
+ }
}
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Modifier/AddUrlToName.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Modifier/AddUrlToName.php
new file mode 100644
index 0000000000000..14a59afc8814b
--- /dev/null
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Modifier/AddUrlToName.php
@@ -0,0 +1,110 @@
+urlBuilder = $urlBuilder;
+ $this->escaper = $escaper;
+ $this->request = $request;
+ $this->storeManager = $storeManager;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function modifyData(array $data): array
+ {
+ if (empty($data)) {
+ return $data;
+ }
+
+ $storeId = $this->getStore()->getId();
+
+ if (!empty($data['items'])) {
+ foreach ($data['items'] as &$item) {
+ if (isset($item['name'])) {
+ $url = $this->urlBuilder->getUrl(
+ 'catalog/product/edit',
+ ['id' => $item['entity_id'], 'store' => $storeId]
+ );
+ $item['name'] = ''
+ . $this->escaper->escapeHtml(
+ $item['name']
+ ) . '';
+ }
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function modifyMeta(array $meta): array
+ {
+ return $meta;
+ }
+
+ /**
+ * Retrieve store
+ *
+ * @return StoreInterface
+ * @throws NoSuchEntityException
+ */
+ private function getStore(): StoreInterface
+ {
+ return $this->storeManager->getStore();
+ }
+}
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/ProductCustomOptionsDataProvider.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/ProductCustomOptionsDataProvider.php
index 6de75e79b56da..0957affe57fc4 100644
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/ProductCustomOptionsDataProvider.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/ProductCustomOptionsDataProvider.php
@@ -47,6 +47,11 @@ class ProductCustomOptionsDataProvider extends ProductDataProvider
*/
private $metadataPool;
+ /**
+ * @var PoolInterface
+ */
+ private $modifiersPool;
+
/**
* @param string $name
* @param string $primaryFieldName
@@ -95,6 +100,7 @@ public function __construct(
$this->productOptionValueModel = $productOptionValueModel;
$this->metadataPool = $metadataPool ?: ObjectManager::getInstance()
->get(MetadataPool::class);
+ $this->modifiersPool = $modifiersPool ?: ObjectManager::getInstance()->get(PoolInterface::class);
}
/**
@@ -144,9 +150,15 @@ public function getData()
$items = $this->getCollection()->toArray();
- return [
+ $data = [
'totalRecords' => $this->getCollection()->getSize(),
'items' => array_values($items),
];
+
+ /** @var ModifierInterface $modifier */
+ foreach ($this->modifiersPool->getModifiersInstances() as $modifier) {
+ $data = $modifier->modifyData($data);
+ }
+ return $data;
}
}
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Related/AbstractDataProvider.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Related/AbstractDataProvider.php
index 8154cab3d9068..404f9de8b1a8f 100644
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Related/AbstractDataProvider.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Related/AbstractDataProvider.php
@@ -12,9 +12,11 @@
use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Framework\App\RequestInterface;
+use Magento\Framework\App\ObjectManager;
use Magento\Catalog\Api\ProductLinkRepositoryInterface;
use Magento\Store\Api\Data\StoreInterface;
use Magento\Store\Api\StoreRepositoryInterface;
+use Magento\Ui\DataProvider\Modifier\PoolInterface;
/**
* Class AbstractDataProvider
@@ -58,6 +60,11 @@ abstract class AbstractDataProvider extends ProductDataProvider
*/
private $store;
+ /**
+ * @var PoolInterface
+ */
+ private $modifiersPool;
+
/**
* @param string $name
* @param string $primaryFieldName
@@ -71,6 +78,7 @@ abstract class AbstractDataProvider extends ProductDataProvider
* @param array $addFilterStrategies
* @param array $meta
* @param array $data
+ * @param PoolInterface|null $modifiersPool
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
@@ -85,7 +93,8 @@ public function __construct(
$addFieldStrategies,
$addFilterStrategies,
array $meta = [],
- array $data = []
+ array $data = [],
+ PoolInterface $modifiersPool = null
) {
parent::__construct(
$name,
@@ -102,6 +111,7 @@ public function __construct(
$this->productRepository = $productRepository;
$this->storeRepository = $storeRepository;
$this->productLinkRepository = $productLinkRepository;
+ $this->modifiersPool = $modifiersPool ?: ObjectManager::getInstance()->get(PoolInterface::class);
}
/**
@@ -205,4 +215,28 @@ protected function getStore()
return $this->store = $this->storeRepository->getById($storeId);
}
+
+ /**
+ * Get data
+ *
+ * @return array
+ */
+ public function getData() : array
+ {
+ if (!$this->getCollection()->isLoaded()) {
+ $this->getCollection()->load();
+ }
+ $items = $this->getCollection()->toArray();
+
+ $data = [
+ 'totalRecords' => $this->getCollection()->getSize(),
+ 'items' => array_values($items),
+ ];
+
+ /** @var ModifierInterface $modifier */
+ foreach ($this->modifiersPool->getModifiersInstances() as $modifier) {
+ $data = $modifier->modifyData($data);
+ }
+ return $data;
+ }
}
diff --git a/app/code/Magento/Catalog/etc/adminhtml/di.xml b/app/code/Magento/Catalog/etc/adminhtml/di.xml
index 8e17c61c3926a..89778ba349eff 100644
--- a/app/code/Magento/Catalog/etc/adminhtml/di.xml
+++ b/app/code/Magento/Catalog/etc/adminhtml/di.xml
@@ -83,6 +83,16 @@
\Magento\Catalog\Ui\DataProvider\Product\ProductCollection
+
+
+ Magento\Catalog\Ui\DataProvider\Product\Name\Modifier\Pool
+
+
+
+
+ Magento\Catalog\Ui\DataProvider\Product\Name\Modifier\Pool
+
+
@@ -184,6 +194,24 @@
+
+
+
+ -
+
- Magento\Catalog\Ui\DataProvider\Product\Modifier\Attributes
+ - 10
+
+ -
+
- Magento\Catalog\Ui\DataProvider\Product\Modifier\PriceAttributes
+ - 10
+
+ -
+
- Magento\Catalog\Ui\DataProvider\Product\Modifier\AddUrlToName
+ - 10
+
+
+
+
diff --git a/app/code/Magento/Catalog/view/adminhtml/ui_component/crosssell_product_listing.xml b/app/code/Magento/Catalog/view/adminhtml/ui_component/crosssell_product_listing.xml
index 1473b043e1edc..9d3d3ad41eea1 100644
--- a/app/code/Magento/Catalog/view/adminhtml/ui_component/crosssell_product_listing.xml
+++ b/app/code/Magento/Catalog/view/adminhtml/ui_component/crosssell_product_listing.xml
@@ -96,6 +96,7 @@
true
text
+ ui/grid/cells/html
@@ -147,5 +148,11 @@
+
+
+ entity_id
+
+
+
diff --git a/app/code/Magento/Catalog/view/adminhtml/ui_component/product_custom_options_listing.xml b/app/code/Magento/Catalog/view/adminhtml/ui_component/product_custom_options_listing.xml
index 0df70675ffd4f..e37f6b2563e2a 100644
--- a/app/code/Magento/Catalog/view/adminhtml/ui_component/product_custom_options_listing.xml
+++ b/app/code/Magento/Catalog/view/adminhtml/ui_component/product_custom_options_listing.xml
@@ -81,6 +81,7 @@
true
text
+ ui/grid/cells/html
diff --git a/app/code/Magento/Catalog/view/adminhtml/ui_component/related_product_listing.xml b/app/code/Magento/Catalog/view/adminhtml/ui_component/related_product_listing.xml
index c62a39b5658c5..c3f782a46a8df 100644
--- a/app/code/Magento/Catalog/view/adminhtml/ui_component/related_product_listing.xml
+++ b/app/code/Magento/Catalog/view/adminhtml/ui_component/related_product_listing.xml
@@ -91,6 +91,7 @@
true
text
+ ui/grid/cells/html
@@ -142,5 +143,11 @@
+
+
+ entity_id
+
+
+
diff --git a/app/code/Magento/Catalog/view/adminhtml/ui_component/upsell_product_listing.xml b/app/code/Magento/Catalog/view/adminhtml/ui_component/upsell_product_listing.xml
index fce4cc1dac8cf..2cdb6998bd180 100644
--- a/app/code/Magento/Catalog/view/adminhtml/ui_component/upsell_product_listing.xml
+++ b/app/code/Magento/Catalog/view/adminhtml/ui_component/upsell_product_listing.xml
@@ -91,6 +91,7 @@
true
text
+ ui/grid/cells/html
@@ -142,5 +143,11 @@
+
+
+ entity_id
+
+
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Ui/DataProvider/Product/ConfigurableDataProviderTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Ui/DataProvider/Product/ConfigurableDataProviderTest.php
new file mode 100644
index 0000000000000..6e1e4760ca4dc
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Ui/DataProvider/Product/ConfigurableDataProviderTest.php
@@ -0,0 +1,122 @@
+assertInstanceOf(ConfigurableDataProvider::class, $this->getModel());
+ }
+
+ /**
+ * Test checks collection type
+ */
+ public function testGetCollection(): void
+ {
+ $this->assertInstanceOf(Collection::class, $this->getModel()->getCollection());
+ }
+
+ /**
+ * @return void
+ */
+ protected function setUp(): void
+ {
+ $this->objectManager = new ObjectManager($this);
+
+ $this->collectionMock = $this->getMockBuilder(Collection::class)
+ ->disableOriginalConstructor()
+ ->setMethods(
+ [
+ 'toArray',
+ 'isLoaded',
+ 'addAttributeToFilter',
+ 'load',
+ 'getSize',
+ 'addFilterByRequiredOptions',
+ 'addStoreFilter'
+ ]
+ )->getMock();
+ $this->collectionFactoryMock = $this->getMockBuilder(CollectionFactory::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['create'])
+ ->getMock();
+ $this->collectionFactoryMock->expects($this->any())
+ ->method('create')
+ ->willReturn($this->collectionMock);
+
+ $this->modifiersPool = $this->getMockBuilder(PoolInterface::class)
+ ->getMockForAbstractClass();
+ $this->modifierMockOne = $this->getMockBuilder(ModifierInterface::class)
+ ->setMethods(['modifyData'])
+ ->getMockForAbstractClass();
+ $this->modifierMockOne->expects($this->any())
+ ->method('modifyData')
+ ->willReturn($this->returnArgument(0));
+ $this->modifiersPool->expects($this->any())
+ ->method('getModifiersInstances')
+ ->willReturn([$this->modifierMockOne]);
+ }
+
+ /**
+ * @return object
+ */
+ private function getModel(): ConfigurableDataProvider
+ {
+ return $this->objectManager->getObject(ConfigurableDataProvider::class, [
+ 'name' => 'testName',
+ 'primaryFieldName' => 'testPrimaryFieldName',
+ 'requestFieldName' => 'testRequestFieldName',
+ 'collectionFactory' => $this->collectionFactoryMock,
+ 'meta' => [],
+ 'data' => [],
+ 'addFieldStrategies' => [],
+ 'addFilterStrategies' => [],
+ 'modifiersPool' => $this->modifiersPool
+ ]);
+ }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/ConfigurableDataProvider.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/ConfigurableDataProvider.php
new file mode 100644
index 0000000000000..22bad9359c74c
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/ConfigurableDataProvider.php
@@ -0,0 +1,55 @@
+Magento\Framework\Serialize\Serializer\Json
+
+
+ Magento\Catalog\Ui\DataProvider\Product\Name\Modifier\Pool
+
+
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/ui_component/configurable_associated_product_listing.xml b/app/code/Magento/ConfigurableProduct/view/adminhtml/ui_component/configurable_associated_product_listing.xml
index c23141d44a2ec..8e9353a2eb4a9 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/ui_component/configurable_associated_product_listing.xml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/ui_component/configurable_associated_product_listing.xml
@@ -25,7 +25,7 @@
Magento_Catalog::products
-
+
id
entity_id
@@ -103,6 +103,7 @@
true
text
+ ui/grid/cells/html
@@ -148,5 +149,11 @@
false
+
+
+ entity_id
+
+
+
diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GroupedTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GroupedTest.php
index 640b8ee52800f..bff5ebc813aa2 100644
--- a/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GroupedTest.php
+++ b/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GroupedTest.php
@@ -14,6 +14,7 @@
use Magento\Catalog\Api\ProductLinkRepositoryInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Helper\Image as ImageHelper;
+use Magento\Catalog\Helper\Product\AddUrlToName as NameHelper;
use Magento\Catalog\Model\Locator\LocatorInterface;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Test\Unit\Ui\DataProvider\Product\Form\Modifier\AbstractModifierTest;
@@ -96,6 +97,11 @@ class GroupedTest extends AbstractModifierTest
*/
private $productLinkFactoryMock;
+ /**
+ * @var NameHelper|MockObject
+ */
+ private $nameHelperMock;
+
/**
* @inheritdoc
*/
@@ -211,6 +217,10 @@ protected function createModel()
->method('get')
->willReturn($attributeSetMock);
+ $this->nameHelperMock = $this->createMock(NameHelper::class);
+ $this->nameHelperMock->method('addUrlToName')
+ ->willReturn(self::LINKED_PRODUCT_NAME);
+
return $this->objectManager->getObject(Grouped::class, [
'locator' => $this->locatorMock,
'productLinkRepository' => $this->linkRepositoryMock,
@@ -220,6 +230,7 @@ protected function createModel()
'attributeSetRepository' => $this->attributeSetRepositoryMock,
'groupedProducts' => $this->groupedProductsMock,
'productLinkFactory' => $this->productLinkFactoryMock,
+ 'nameHelper' => $this->nameHelperMock
]);
}
@@ -270,7 +281,7 @@ public function testModifyData()
$linkedProductMock->expects($this->once())
->method('getId')
->willReturn(self::LINKED_PRODUCT_ID);
- $linkedProductMock->expects($this->once())
+ $linkedProductMock->expects($this->any())
->method('getName')
->willReturn(self::LINKED_PRODUCT_NAME);
$linkedProductMock->expects($this->once())
diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/GroupedProductDataProviderTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/GroupedProductDataProviderTest.php
index 3a400062d2d0c..bcc3654ed29c6 100644
--- a/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/GroupedProductDataProviderTest.php
+++ b/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/GroupedProductDataProviderTest.php
@@ -13,6 +13,8 @@
use Magento\Framework\App\RequestInterface;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\GroupedProduct\Ui\DataProvider\Product\GroupedProductDataProvider;
+use Magento\Ui\DataProvider\Modifier\ModifierInterface;
+use Magento\Ui\DataProvider\Modifier\PoolInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
@@ -45,6 +47,16 @@ class GroupedProductDataProviderTest extends TestCase
*/
protected $configMock;
+ /**
+ * @var PoolInterface|MockObject
+ */
+ private $modifiersPool;
+
+ /**
+ * @var ModifierInterface|MockObject
+ */
+ private $modifierMockOne;
+
/**
* @return void
*/
@@ -77,6 +89,18 @@ protected function setUp(): void
$this->configMock = $this->getMockBuilder(ConfigInterface::class)
->setMethods(['getComposableTypes'])
->getMockForAbstractClass();
+
+ $this->modifiersPool = $this->getMockBuilder(PoolInterface::class)
+ ->getMockForAbstractClass();
+ $this->modifierMockOne = $this->getMockBuilder(ModifierInterface::class)
+ ->setMethods(['modifyData'])
+ ->getMockForAbstractClass();
+ $this->modifierMockOne->expects($this->any())
+ ->method('modifyData')
+ ->willReturn($this->returnArgument(0));
+ $this->modifiersPool->expects($this->any())
+ ->method('getModifiersInstances')
+ ->willReturn([$this->modifierMockOne]);
}
/**
@@ -95,6 +119,7 @@ protected function getModel()
'addFilterStrategies' => [],
'meta' => [],
'data' => [],
+ 'modifiersPool' => $this->modifiersPool
]);
}
diff --git a/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php b/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php
index 12a21a4ebd04b..b404016c8de95 100644
--- a/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php
+++ b/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php
@@ -24,6 +24,7 @@
use Magento\GroupedProduct\Model\Product\Link\CollectionProvider\Grouped as GroupedProducts;
use Magento\Framework\App\ObjectManager;
use Magento\Catalog\Api\Data\ProductLinkInterfaceFactory;
+use Magento\Catalog\Helper\Product\AddUrlToName as NameHelper;
/**
* Data provider for Grouped products
@@ -112,6 +113,11 @@ class Grouped extends AbstractModifier
*/
private $productLinkFactory;
+ /**
+ * @var NameHelper
+ */
+ private $nameHelper;
+
/**
* @param LocatorInterface $locator
* @param UrlInterface $urlBuilder
@@ -121,6 +127,7 @@ class Grouped extends AbstractModifier
* @param Status $status
* @param AttributeSetRepositoryInterface $attributeSetRepository
* @param CurrencyInterface $localeCurrency
+ * @param NameHelper $nameHelper
* @param array $uiComponentsConfig
* @param GroupedProducts $groupedProducts
* @param \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory|null $productLinkFactory
@@ -135,6 +142,7 @@ public function __construct(
Status $status,
AttributeSetRepositoryInterface $attributeSetRepository,
CurrencyInterface $localeCurrency,
+ NameHelper $nameHelper,
array $uiComponentsConfig = [],
GroupedProducts $groupedProducts = null,
\Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory = null
@@ -147,6 +155,7 @@ public function __construct(
$this->attributeSetRepository = $attributeSetRepository;
$this->status = $status;
$this->localeCurrency = $localeCurrency;
+ $this->nameHelper = $nameHelper;
$this->uiComponentsConfig = array_replace_recursive($this->uiComponentsConfig, $uiComponentsConfig);
$this->groupedProducts = $groupedProducts ?: ObjectManager::getInstance()->get(
\Magento\GroupedProduct\Model\Product\Link\CollectionProvider\Grouped::class
@@ -196,7 +205,7 @@ protected function fillData(ProductInterface $linkedProduct, ProductLinkInterfac
return [
'id' => $linkedProduct->getId(),
- 'name' => $linkedProduct->getName(),
+ 'name' => $this->nameHelper->addUrlToName($linkedProduct),
'sku' => $linkedProduct->getSku(),
'price' => $currency->toCurrency(sprintf("%f", $linkedProduct->getPrice())),
'qty' => $linkedProduct->getQty(),
@@ -567,7 +576,7 @@ protected function fillMeta()
],
],
],
- 'name' => $this->getTextColumn('name', false, __('Name'), 30),
+ 'name' => $this->getHtmlColumn('name', false, __('Name'), 30),
'attribute_set' => $this->getTextColumn('attribute_set', false, __('Attribute Set'), 40),
'status' => $this->getTextColumn('status', true, __('Status'), 50),
'sku' => $this->getTextColumn('sku', false, __('SKU'), 60),
@@ -670,4 +679,36 @@ protected function getTextColumn($dataScope, $fit, Phrase $label, $sortOrder)
];
return $column;
}
+
+ /**
+ * Returns html column configuration for the dynamic grid
+ *
+ * @param string $dataScope
+ * @param bool $fit
+ * @param Phrase $label
+ * @param int $sortOrder
+ * @return array
+ */
+ protected function getHtmlColumn($dataScope, $fit, Phrase $label, $sortOrder) : array
+ {
+ $column = [
+ 'arguments' => [
+ 'data' => [
+ 'config' => [
+ 'componentType' => Form\Field::NAME,
+ 'formElement' => Form\Element\Input::NAME,
+ 'elementTmpl' => 'Magento_GroupedProduct/components/cell-html',
+ 'dataType' => Form\Element\DataType\Text::NAME,
+ 'dataScope' => $dataScope,
+ 'fit' => $fit,
+ 'label' => $label,
+ 'sortOrder' => $sortOrder,
+ 'labelVisible' => false,
+ ],
+ ],
+ ],
+ ];
+
+ return $column;
+ }
}
diff --git a/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/GroupedProductDataProvider.php b/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/GroupedProductDataProvider.php
index 5af6d515fe266..8b324e62a52fe 100644
--- a/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/GroupedProductDataProvider.php
+++ b/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/GroupedProductDataProvider.php
@@ -7,6 +7,7 @@
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider;
+use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Catalog\Model\ProductTypes\ConfigInterface;
use Magento\Framework\App\RequestInterface;
@@ -14,6 +15,7 @@
use Magento\Store\Api\StoreRepositoryInterface;
use Magento\Ui\DataProvider\AddFieldToCollectionInterface;
use Magento\Ui\DataProvider\AddFilterToCollectionInterface;
+use Magento\Ui\DataProvider\Modifier\PoolInterface;
class GroupedProductDataProvider extends ProductDataProvider
{
@@ -32,6 +34,11 @@ class GroupedProductDataProvider extends ProductDataProvider
*/
protected $storeRepository;
+ /**
+ * @var PoolInterface
+ */
+ private $modifiersPool;
+
/**
* Construct
*
@@ -46,6 +53,7 @@ class GroupedProductDataProvider extends ProductDataProvider
* @param array $data
* @param AddFieldToCollectionInterface[] $addFieldStrategies
* @param AddFilterToCollectionInterface[] $addFilterStrategies
+ * @param PoolInterface|null $modifiersPool
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
@@ -59,7 +67,8 @@ public function __construct(
array $meta = [],
array $data = [],
array $addFieldStrategies = [],
- array $addFilterStrategies = []
+ array $addFilterStrategies = [],
+ PoolInterface $modifiersPool = null
) {
parent::__construct(
$name,
@@ -75,6 +84,7 @@ public function __construct(
$this->request = $request;
$this->storeRepository = $storeRepository;
$this->config = $config;
+ $this->modifiersPool = $modifiersPool ?: ObjectManager::getInstance()->get(PoolInterface::class);
}
/**
@@ -103,9 +113,15 @@ public function getData()
}
$items = $this->getCollection()->toArray();
- return [
+ $data = [
'totalRecords' => $this->getCollection()->getSize(),
'items' => array_values($items),
];
+
+ /** @var ModifierInterface $modifier */
+ foreach ($this->modifiersPool->getModifiersInstances() as $modifier) {
+ $data = $modifier->modifyData($data);
+ }
+ return $data;
}
}
diff --git a/app/code/Magento/GroupedProduct/etc/di.xml b/app/code/Magento/GroupedProduct/etc/di.xml
index 8b58ac08ebd31..0dea71eeca406 100644
--- a/app/code/Magento/GroupedProduct/etc/di.xml
+++ b/app/code/Magento/GroupedProduct/etc/di.xml
@@ -128,4 +128,9 @@
+
+
+ Magento\Catalog\Ui\DataProvider\Product\Name\Modifier\Pool
+
+
diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/ui_component/grouped_product_listing.xml b/app/code/Magento/GroupedProduct/view/adminhtml/ui_component/grouped_product_listing.xml
index becd7ca8079da..a451c31932507 100644
--- a/app/code/Magento/GroupedProduct/view/adminhtml/ui_component/grouped_product_listing.xml
+++ b/app/code/Magento/GroupedProduct/view/adminhtml/ui_component/grouped_product_listing.xml
@@ -104,6 +104,7 @@
true
text
+ ui/grid/cells/html
@@ -165,5 +166,11 @@
false
+
+
+ entity_id
+
+
+
diff --git a/code/Magento/Catalog/Ui/DataProvider/Product/Modifier/AddUrlToName.php b/code/Magento/Catalog/Ui/DataProvider/Product/Modifier/AddUrlToName.php
new file mode 100644
index 0000000000000..14a59afc8814b
--- /dev/null
+++ b/code/Magento/Catalog/Ui/DataProvider/Product/Modifier/AddUrlToName.php
@@ -0,0 +1,110 @@
+urlBuilder = $urlBuilder;
+ $this->escaper = $escaper;
+ $this->request = $request;
+ $this->storeManager = $storeManager;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function modifyData(array $data): array
+ {
+ if (empty($data)) {
+ return $data;
+ }
+
+ $storeId = $this->getStore()->getId();
+
+ if (!empty($data['items'])) {
+ foreach ($data['items'] as &$item) {
+ if (isset($item['name'])) {
+ $url = $this->urlBuilder->getUrl(
+ 'catalog/product/edit',
+ ['id' => $item['entity_id'], 'store' => $storeId]
+ );
+ $item['name'] = ''
+ . $this->escaper->escapeHtml(
+ $item['name']
+ ) . '';
+ }
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function modifyMeta(array $meta): array
+ {
+ return $meta;
+ }
+
+ /**
+ * Retrieve store
+ *
+ * @return StoreInterface
+ * @throws NoSuchEntityException
+ */
+ private function getStore(): StoreInterface
+ {
+ return $this->storeManager->getStore();
+ }
+}
diff --git a/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/ConfigurableDataProvider.php b/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/ConfigurableDataProvider.php
new file mode 100644
index 0000000000000..22bad9359c74c
--- /dev/null
+++ b/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/ConfigurableDataProvider.php
@@ -0,0 +1,55 @@
+