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