From bd7c28f2d552d772afba5ff0660d6c8b0b875288 Mon Sep 17 00:00:00 2001 From: jekabs Date: Thu, 8 Oct 2020 18:11:48 +0300 Subject: [PATCH 1/7] Giftcard options -Added label and render_type to gift card option test --- .../ProductOptions/GiftCardProductTest.php | 94 +++++++++++++++---- 1 file changed, 74 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/GiftCardProductTest.php b/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/GiftCardProductTest.php index 72efc2eeb..973fc1b54 100644 --- a/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/GiftCardProductTest.php +++ b/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/GiftCardProductTest.php @@ -190,6 +190,8 @@ public function getGiftCardProductProvider(): array [ 'productOptions' => [ [ + 'label' => 'Amount', + 'render_type' => 'drop_down', 'type' => 'giftcard', 'values' => [ // phpcs:ignore Magento2.Functions.DiscouragedFunction @@ -198,10 +200,18 @@ public function getGiftCardProductProvider(): array ] ], 'productShopperInputOptions' => [ - // phpcs:ignore Magento2.Functions.DiscouragedFunction - ['id' => \base64_encode('giftcard/giftcard_recipient_name')], - // phpcs:ignore Magento2.Functions.DiscouragedFunction - ['id' => \base64_encode('giftcard/giftcard_sender_name')] + [ + // phpcs:ignore Magento2.Functions.DiscouragedFunction + 'id' => \base64_encode('giftcard/giftcard_sender_name'), + 'label' => 'Sender Name', + 'render_type' => 'text' + ], + [ + // phpcs:ignore Magento2.Functions.DiscouragedFunction + 'id' => \base64_encode('giftcard/giftcard_recipient_name'), + 'label' => 'Recipient Name', + 'render_type' => 'text' + ] ] ] ]; @@ -218,6 +228,8 @@ public function getVirtualMultiWebsiteDataProvider(): array [ 'defaultWebsiteOptions' => [ [ + 'label' => 'Amount', + 'render_type' => 'drop_down', 'type' => 'giftcard', 'values' => [ // phpcs:ignore Magento2.Functions.DiscouragedFunction @@ -228,17 +240,35 @@ public function getVirtualMultiWebsiteDataProvider(): array ] ], 'defaultWebsiteInputOptions' => [ - // phpcs:ignore Magento2.Functions.DiscouragedFunction - ['id' => \base64_encode('giftcard/giftcard_recipient_name')], - // phpcs:ignore Magento2.Functions.DiscouragedFunction - ['id' => \base64_encode('giftcard/giftcard_sender_name')], - // phpcs:ignore Magento2.Functions.DiscouragedFunction - ['id' => \base64_encode('giftcard/giftcard_recipient_email')], - // phpcs:ignore Magento2.Functions.DiscouragedFunction - ['id' => \base64_encode('giftcard/giftcard_sender_email')], + [ + // phpcs:ignore Magento2.Functions.DiscouragedFunction + 'id' => \base64_encode('giftcard/giftcard_sender_name'), + 'label' => 'Sender Name', + 'render_type' => 'text' + ], + [ + // phpcs:ignore Magento2.Functions.DiscouragedFunction + 'id' => \base64_encode('giftcard/giftcard_recipient_name'), + 'label' => 'Recipient Name', + 'render_type' => 'text' + ], + [ + // phpcs:ignore Magento2.Functions.DiscouragedFunction + 'id' => \base64_encode('giftcard/giftcard_sender_email'), + 'label' => 'Sender Email', + 'render_type' => 'email' + ], + [ + // phpcs:ignore Magento2.Functions.DiscouragedFunction + 'id' => \base64_encode('giftcard/giftcard_recipient_email'), + 'label' => 'Recipient Email', + 'render_type' => 'email' + ], [ // phpcs:ignore Magento2.Functions.DiscouragedFunction 'id' => \base64_encode('giftcard/giftcard_message'), + 'label' => 'Message', + 'render_type' => 'text', 'range' => [ 'from' => 0.0, 'to' => 255.0 @@ -247,6 +277,8 @@ public function getVirtualMultiWebsiteDataProvider(): array [ // phpcs:ignore Magento2.Functions.DiscouragedFunction 'id' => \base64_encode('giftcard/custom_giftcard_amount'), + 'label' => 'Amount in', + 'render_type' => 'giftcardopenamount', 'range' => [ 'from' => 100.0, 'to' => 150.0 @@ -255,6 +287,8 @@ public function getVirtualMultiWebsiteDataProvider(): array ], 'secondWebsiteOptions' => [ [ + 'label' => 'Amount', + 'render_type' => 'drop_down', 'type' => 'giftcard', 'values' => [ // phpcs:ignore Magento2.Functions.DiscouragedFunction @@ -265,17 +299,35 @@ public function getVirtualMultiWebsiteDataProvider(): array ] ], 'secondWebsiteInputOptions' => [ - // phpcs:ignore Magento2.Functions.DiscouragedFunction - ['id' => \base64_encode('giftcard/giftcard_recipient_name')], - // phpcs:ignore Magento2.Functions.DiscouragedFunction - ['id' => \base64_encode('giftcard/giftcard_sender_name')], - // phpcs:ignore Magento2.Functions.DiscouragedFunction - ['id' => \base64_encode('giftcard/giftcard_recipient_email')], - // phpcs:ignore Magento2.Functions.DiscouragedFunction - ['id' => \base64_encode('giftcard/giftcard_sender_email')], + [ + // phpcs:ignore Magento2.Functions.DiscouragedFunction + 'id' => \base64_encode('giftcard/giftcard_sender_name'), + 'label' => 'Sender Name', + 'render_type' => 'text' + ], + [ + // phpcs:ignore Magento2.Functions.DiscouragedFunction + 'id' => \base64_encode('giftcard/giftcard_recipient_name'), + 'label' => 'Recipient Name', + 'render_type' => 'text' + ], + [ + // phpcs:ignore Magento2.Functions.DiscouragedFunction + 'id' => \base64_encode('giftcard/giftcard_sender_email'), + 'label' => 'Sender Email', + 'render_type' => 'email' + ], + [ + // phpcs:ignore Magento2.Functions.DiscouragedFunction + 'id' => \base64_encode('giftcard/giftcard_recipient_email'), + 'label' => 'Recipient Email', + 'render_type' => 'email' + ], [ // phpcs:ignore Magento2.Functions.DiscouragedFunction 'id' => \base64_encode('giftcard/giftcard_message'), + 'label' => 'Message', + 'render_type' => 'text', 'range' => [ 'from' => 0.0, 'to' => 255.0 @@ -284,6 +336,8 @@ public function getVirtualMultiWebsiteDataProvider(): array [ // phpcs:ignore Magento2.Functions.DiscouragedFunction 'id' => \base64_encode('giftcard/custom_giftcard_amount'), + 'label' => 'Amount in', + 'render_type' => 'giftcardopenamount', 'range' => [ 'from' => 100.0, 'to' => 150.0 From 4e96d8d8d4764e7a64505a2a726e0be4e3bd9dc1 Mon Sep 17 00:00:00 2001 From: Aleksejs Baranovs Date: Fri, 9 Oct 2020 15:15:08 +0300 Subject: [PATCH 2/7] Product images not found for SF API - Sample url change --- .../Api/Product/Downloadable/SamplesTest.php | 49 +++++++++++++------ .../ProductOptions/DownloadLinksTest.php | 7 ++- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/CatalogStorefront/Test/Api/Product/Downloadable/SamplesTest.php b/app/code/Magento/CatalogStorefront/Test/Api/Product/Downloadable/SamplesTest.php index 79f129ae7..1ca5aaea2 100644 --- a/app/code/Magento/CatalogStorefront/Test/Api/Product/Downloadable/SamplesTest.php +++ b/app/code/Magento/CatalogStorefront/Test/Api/Product/Downloadable/SamplesTest.php @@ -63,36 +63,49 @@ protected function setUp(): void * Validate downloadable product data * * @magentoDataFixture Magento_CatalogStorefront::Test/Api/Product/Downloadable/_files/sf_product_downloadable_with_urls.php + * @dataProvider downloadableUrlsProvider + * * @magentoDbIsolation disabled + * * @param array $expected + * * @throws NoSuchEntityException - * @dataProvider downloadableUrlsProvider + * @throws \Throwable */ public function testDownloadableProductsWithUrls(array $expected): void { - $product = $this->productRepository->get(self::TEST_SKU); - - $this->productsGetRequestInterface->setIds([$product->getId()]); - $this->productsGetRequestInterface->setStore(self::STORE_CODE); - $this->productsGetRequestInterface->setAttributeCodes(['samples']); - $catalogServiceItem = $this->catalogService->getProducts($this->productsGetRequestInterface); - self::assertNotEmpty($catalogServiceItem->getItems()); - - $actual = $this->arrayMapper->convertToArray($catalogServiceItem->getItems()[0]->getSamples()[0]); - - $this->compare($expected, $actual); + $this->validateSampleData($expected); } /** * Validate downloadable product data * * @magentoDataFixture Magento/Downloadable/_files/product_downloadable_with_files.php + * @dataProvider downloadableFilesProvider + * * @magentoDbIsolation disabled + * * @param array $expected + * * @throws NoSuchEntityException - * @dataProvider downloadableFilesProvider + * @throws \Throwable */ public function testDownloadableProductsWithFiles(array $expected): void + { + $this->validateSampleData($expected); + } + + /** + * Validate sample data + * + * @param array $dataProvider + * + * @return void + * + * @throws NoSuchEntityException + * @throws \Throwable + */ + private function validateSampleData(array $dataProvider) : void { $product = $this->productRepository->get(self::TEST_SKU); @@ -104,7 +117,13 @@ public function testDownloadableProductsWithFiles(array $expected): void $actual = $this->arrayMapper->convertToArray($catalogServiceItem->getItems()[0]->getSamples()[0]); - $this->compare($expected, $actual); + $this->compare($dataProvider, $actual); + + $sample = $product->getExtensionAttributes()->getDownloadableProductSamples()[0]; + self::assertStringEndsWith( + \sprintf('/downloadable/download/sample/sample_id/%s', $sample->getId()), + $actual['resource']['url'] + ); } /** @@ -118,7 +137,6 @@ public function downloadableUrlsProvider(): array [ [ 'resource' => [ - 'url' => 'http://example.com/downloadable.txt', 'label' => 'Downloadable Product Sample', 'roles' => [], ], @@ -139,7 +157,6 @@ public function downloadableFilesProvider(): array [ [ 'resource' => [ - 'url' => '/j/e/jellyfish_1_4.jpg', 'label' => 'Downloadable Product Sample Title', 'roles' => [], ], diff --git a/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/DownloadLinksTest.php b/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/DownloadLinksTest.php index cfd956b83..ad6505de9 100644 --- a/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/DownloadLinksTest.php +++ b/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/DownloadLinksTest.php @@ -136,6 +136,12 @@ public function testDownloadableLinksFileOptionData(array $expected): void } $this->compare($expected, $actual); + + $link = $product->getExtensionAttributes()->getDownloadableProductLinks()[0]; + self::assertStringEndsWith( + \sprintf('/downloadable/download/linkSample/link_id/%s', $link->getId()), + $actual[0]['values'][0]['info_url'] + ); } /** @@ -200,7 +206,6 @@ public function downloadableLinkFileProvider(): array 'image_url' => '', 'qty_mutability' => false, 'qty' => 0.0, - 'info_url' => '/j/e/jellyfish_1_3.jpg', 'price' => 15.0 ] ] From 7ed9bc82fb25d538ed1be3bc53b5d1c13b65981f Mon Sep 17 00:00:00 2001 From: Aleksejs Baranovs Date: Mon, 12 Oct 2020 13:41:04 +0300 Subject: [PATCH 3/7] Product images not found for SF API - Sample url change --- .../Test/Api/Product/Downloadable/SamplesTest.php | 14 ++++++++++++-- .../Product/ProductOptions/DownloadLinksTest.php | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CatalogStorefront/Test/Api/Product/Downloadable/SamplesTest.php b/app/code/Magento/CatalogStorefront/Test/Api/Product/Downloadable/SamplesTest.php index 1ca5aaea2..1f438d935 100644 --- a/app/code/Magento/CatalogStorefront/Test/Api/Product/Downloadable/SamplesTest.php +++ b/app/code/Magento/CatalogStorefront/Test/Api/Product/Downloadable/SamplesTest.php @@ -13,6 +13,8 @@ use Magento\CatalogStorefrontApi\Api\Data\ProductsGetRequestInterface; use Magento\CatalogStorefrontApi\Api\Data\SampleArrayMapper; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\UrlInterface; +use Magento\Store\Model\StoreManagerInterface; use Magento\TestFramework\Helper\Bootstrap; /** @@ -47,6 +49,11 @@ class SamplesTest extends StorefrontTestsAbstract */ private $arrayMapper; + /** + * @var StoreManagerInterface + */ + private $storeManager; + /** * @inheritdoc */ @@ -57,6 +64,7 @@ protected function setUp(): void $this->productsGetRequestInterface = Bootstrap::getObjectManager()->create(ProductsGetRequestInterface::class); $this->productRepository = Bootstrap::getObjectManager()->create(ProductRepositoryInterface::class); $this->arrayMapper = Bootstrap::getObjectManager()->create(SampleArrayMapper::class); + $this->storeManager = Bootstrap::getObjectManager()->create(StoreManagerInterface::class); } /** @@ -119,9 +127,11 @@ private function validateSampleData(array $dataProvider) : void $this->compare($dataProvider, $actual); + $baseUrl = $this->storeManager->getStore(self::STORE_CODE)->getBaseUrl(UrlInterface::URL_TYPE_WEB); $sample = $product->getExtensionAttributes()->getDownloadableProductSamples()[0]; - self::assertStringEndsWith( - \sprintf('/downloadable/download/sample/sample_id/%s', $sample->getId()), + + self::assertEquals( + \sprintf('%sdownloadable/download/sample/sample_id/%s', $baseUrl, $sample->getId()), $actual['resource']['url'] ); } diff --git a/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/DownloadLinksTest.php b/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/DownloadLinksTest.php index ad6505de9..fd11af355 100644 --- a/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/DownloadLinksTest.php +++ b/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/DownloadLinksTest.php @@ -13,6 +13,8 @@ use Magento\CatalogStorefrontApi\Api\Data\ProductsGetRequestInterface; use Magento\CatalogStorefrontApi\Api\Data\ProductOptionArrayMapper; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\UrlInterface; +use Magento\Store\Model\StoreManagerInterface; use Magento\TestFramework\Helper\Bootstrap; /** @@ -54,6 +56,11 @@ class DownloadLinksTest extends StorefrontTestsAbstract */ protected $arrayMapper; + /** + * @var StoreManagerInterface + */ + private $storeManager; + /** * @inheritdoc */ @@ -64,6 +71,7 @@ protected function setUp(): void $this->productsGetRequestInterface = Bootstrap::getObjectManager()->create(ProductsGetRequestInterface::class); $this->productRepository = Bootstrap::getObjectManager()->create(ProductRepositoryInterface::class); $this->arrayMapper = Bootstrap::getObjectManager()->create(ProductOptionArrayMapper::class); + $this->storeManager = Bootstrap::getObjectManager()->create(StoreManagerInterface::class); } /** @@ -137,9 +145,11 @@ public function testDownloadableLinksFileOptionData(array $expected): void $this->compare($expected, $actual); + $baseUrl = $this->storeManager->getStore(self::STORE_CODE)->getBaseUrl(UrlInterface::URL_TYPE_WEB); $link = $product->getExtensionAttributes()->getDownloadableProductLinks()[0]; - self::assertStringEndsWith( - \sprintf('/downloadable/download/linkSample/link_id/%s', $link->getId()), + + self::assertEquals( + \sprintf('%sdownloadable/download/linkSample/link_id/%s', $baseUrl, $link->getId()), $actual[0]['values'][0]['info_url'] ); } From 20925efa10018ab7560637316323c99ed9cee749 Mon Sep 17 00:00:00 2001 From: jekabs Date: Mon, 12 Oct 2020 18:30:29 +0300 Subject: [PATCH 4/7] Giftcard options -Suppresed excessive method length warning on test class data provider --- .../Test/Api/Product/ProductOptions/GiftCardProductTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/GiftCardProductTest.php b/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/GiftCardProductTest.php index 973fc1b54..07ac3f826 100644 --- a/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/GiftCardProductTest.php +++ b/app/code/Magento/CatalogStorefront/Test/Api/Product/ProductOptions/GiftCardProductTest.php @@ -220,6 +220,7 @@ public function getGiftCardProductProvider(): array /** * Virtual gift card with fixed and open amount data provider * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) * @return array */ public function getVirtualMultiWebsiteDataProvider(): array From b966db8c7b19c8f1471f254ea0f17c128e0a7a36 Mon Sep 17 00:00:00 2001 From: Aleksejs Baranovs Date: Tue, 13 Oct 2020 14:59:30 +0300 Subject: [PATCH 5/7] gRPC call should return all requested data - Removing catalog service manual data mapping --- .../Model/CatalogService.php | 193 ++---------------- 1 file changed, 16 insertions(+), 177 deletions(-) diff --git a/app/code/Magento/CatalogStorefront/Model/CatalogService.php b/app/code/Magento/CatalogStorefront/Model/CatalogService.php index fb6011d17..9f8c743d7 100644 --- a/app/code/Magento/CatalogStorefront/Model/CatalogService.php +++ b/app/code/Magento/CatalogStorefront/Model/CatalogService.php @@ -13,9 +13,8 @@ use Magento\CatalogStorefrontApi\Api\Data\CategoriesGetRequestInterface; use Magento\CatalogStorefrontApi\Api\Data\CategoriesGetResponse; use Magento\CatalogStorefrontApi\Api\Data\CategoriesGetResponseInterface; -use Magento\CatalogStorefrontApi\Api\Data\Category; use Magento\CatalogStorefrontApi\Api\Data\CategoryArrayMapper; -use Magento\CatalogStorefrontApi\Api\Data\CategoryInterface; +use Magento\CatalogStorefrontApi\Api\Data\CategoryMapper; use Magento\CatalogStorefrontApi\Api\Data\DeleteCategoriesRequestInterface; use Magento\CatalogStorefrontApi\Api\Data\DeleteCategoriesResponseFactory; use Magento\CatalogStorefrontApi\Api\Data\DeleteCategoriesResponseInterface; @@ -24,7 +23,6 @@ use Magento\CatalogStorefrontApi\Api\Data\DeleteProductsResponseFactory; use Magento\CatalogStorefrontApi\Api\Data\DeleteProductsResponseInterface; use Magento\CatalogStorefrontApi\Api\Data\DeleteProductsResponseInterfaceFactory; -use Magento\CatalogStorefrontApi\Api\Data\DynamicAttributeValueInterfaceFactory; use Magento\CatalogStorefrontApi\Api\Data\ImportCategoriesRequestInterface; use Magento\CatalogStorefrontApi\Api\Data\ImportCategoriesResponseFactory; use Magento\CatalogStorefrontApi\Api\Data\ImportCategoriesResponseInterface; @@ -32,14 +30,10 @@ use Magento\CatalogStorefrontApi\Api\Data\ImportProductsResponseFactory; use Magento\CatalogStorefrontApi\Api\Data\ImportProductsResponseInterface; use Magento\CatalogStorefrontApi\Api\Data\ProductArrayMapper; -use Magento\CatalogStorefrontApi\Api\Data\ProductInterface; use Magento\CatalogStorefrontApi\Api\Data\ProductMapper; use Magento\CatalogStorefrontApi\Api\Data\ProductsGetRequestInterface; use Magento\CatalogStorefrontApi\Api\Data\ProductsGetResult; use Magento\CatalogStorefrontApi\Api\Data\ProductsGetResultInterface; -use Magento\CatalogStorefrontApi\Api\Data\UrlRewrite; -use Magento\CatalogStorefrontApi\Api\Data\UrlRewriteParameter; -use Magento\Framework\Api\DataObjectHelper; use Psr\Log\LoggerInterface; /** @@ -57,11 +51,6 @@ class CatalogService implements CatalogServerInterface */ private $dataProvider; - /** - * @var DataObjectHelper - */ - private $dataObjectHelper; - /** * @var ImportProductsResponseFactory */ @@ -92,11 +81,6 @@ class CatalogService implements CatalogServerInterface */ private $categoryDataProvider; - /** - * @var DynamicAttributeValueInterfaceFactory - */ - private $dynamicAttributeFactory; - /** * @var ProductArrayMapper */ @@ -117,11 +101,14 @@ class CatalogService implements CatalogServerInterface */ private $productMapper; + /** + * @var CategoryMapper + */ + private $categoryMapper; + /** * @param ProductDataProvider $dataProvider - * @param DataObjectHelper $dataObjectHelper * @param CategoryDataProvider $categoryDataProvider - * @param DynamicAttributeValueInterfaceFactory $dynamicAttributeFactory * @param ImportProductsResponseFactory $importProductsResponseFactory * @param DeleteProductsResponseFactory $deleteProductsResponseFactory * @param DeleteCategoriesResponseFactory $deleteCategoriesResponseFactory @@ -130,14 +117,13 @@ class CatalogService implements CatalogServerInterface * @param ProductArrayMapper $productArrayMapper * @param CategoryArrayMapper $categoryArrayMapper * @param ProductMapper $productMapper + * @param CategoryMapper $categoryMapper * @param LoggerInterface $logger * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( ProductDataProvider $dataProvider, - DataObjectHelper $dataObjectHelper, CategoryDataProvider $categoryDataProvider, - DynamicAttributeValueInterfaceFactory $dynamicAttributeFactory, ImportProductsResponseFactory $importProductsResponseFactory, DeleteProductsResponseFactory $deleteProductsResponseFactory, DeleteCategoriesResponseFactory $deleteCategoriesResponseFactory, @@ -146,20 +132,20 @@ public function __construct( ProductArrayMapper $productArrayMapper, CategoryArrayMapper $categoryArrayMapper, ProductMapper $productMapper, + CategoryMapper $categoryMapper, LoggerInterface $logger ) { $this->dataProvider = $dataProvider; - $this->dataObjectHelper = $dataObjectHelper; $this->importProductsResponseFactory = $importProductsResponseFactory; $this->deleteProductsResponseFactory = $deleteProductsResponseFactory; $this->deleteCategoriesResponseFactory = $deleteCategoriesResponseFactory; $this->importCategoriesResponseFactory = $importCategoriesResponseFactory; $this->catalogRepository = $catalogRepository; $this->categoryDataProvider = $categoryDataProvider; - $this->dynamicAttributeFactory = $dynamicAttributeFactory; $this->productArrayMapper = $productArrayMapper; $this->categoryArrayMapper = $categoryArrayMapper; $this->productMapper = $productMapper; + $this->categoryMapper = $categoryMapper; $this->logger = $logger; } @@ -200,7 +186,7 @@ public function getProducts( $products = []; foreach ($rawItems as $item) { - $products[] = $this->prepareProduct($item); + $products[] = $this->productMapper->setData($item)->build(); } $result->setItems($products); @@ -208,25 +194,6 @@ public function getProducts( return $result; } - /** - * Unset null values in provided array recursively - * - * @param array $array - * @return array - */ - private function cleanUpNullValues(array $array): array - { - $result = []; - foreach ($array as $key => $value) { - if ($value === null || $value === '') { - continue; - } - - $result[$key] = is_array($value) ? $this->cleanUpNullValues($value) : $value; - } - return $result; - } - /** * Import requested products * @@ -245,41 +212,16 @@ public function importProducts(ImportProductsRequestInterface $request): ImportP foreach ($request->getProducts() as $productData) { $product = $this->productArrayMapper->convertToArray($productData->getProduct()); + $product['store_code'] = $storeCode; if (!empty($productData->getAttributes())) { $product = \array_filter($product, function ($code) use ($productData) { return \in_array($code, $productData->getAttributes()); }, ARRAY_FILTER_USE_KEY); - } - - if (empty($product)) { - continue; - } - $productInElasticFormat = $product; - $productInElasticFormat['store_code'] = $storeCode; - - if (isset($productInElasticFormat['dynamic_attributes'])) { - foreach ($productInElasticFormat['dynamic_attributes'] as $dynamicAttribute) { - $productInElasticFormat[$dynamicAttribute['code']] = $dynamicAttribute['value']; - } - unset($productInElasticFormat['dynamic_attributes']); - } - - if (isset($productInElasticFormat['short_description'])) { - $productInElasticFormat['short_description'] = [ - 'html' => $productInElasticFormat['short_description'] - ]; - } - - if (isset($productInElasticFormat['description'])) { - $productInElasticFormat['description'] = ['html' => $productInElasticFormat['description']]; - } - - if (!empty($productData->getAttributes())) { - $productsInElasticFormat['product'][$storeCode]['update'][] = $productInElasticFormat; + $productsInElasticFormat['product'][$storeCode]['update'][] = $product; } else { - $productsInElasticFormat['product'][$storeCode]['save'][] = $productInElasticFormat; + $productsInElasticFormat['product'][$storeCode]['save'][] = $product; } } @@ -436,114 +378,11 @@ public function getCategories( $items = []; foreach ($categories as $category) { - //We need to bypass inactive categories - if (isset($category['is_active']) && $category['is_active'] == 0) { - continue; - } - $item = new Category(); - $category = $this->cleanUpNullValues($category); - - $this->dataObjectHelper->populateWithArray($item, $category, CategoryInterface::class); - - $children = []; - foreach ($category['children'] ?? [] as $categoryId) { - $children[$categoryId] = $categoryId; - } - $item->setChildren($children); - $items[] = $item; + $items[] = $this->categoryMapper->setData($category)->build(); } - $result->setItems($items); - return $result; - } - - /** - * Prepare product from raw data - * - * @param array $item - * @return ProductInterface - */ - private function prepareProduct(array $item): ProductInterface - { - $item = $this->cleanUpNullValues($item); - - $item['description'] = $item['description']['html'] ?? ''; - $item['short_description'] = $item['short_description']['html'] ?? ''; - //Convert option values to unified array format - if (!empty($item['options'])) { - foreach ($item['options'] as &$option) { - $firstValue = reset($option['value']); - if (!is_array($firstValue)) { - $option['value'] = [0 => $option['value']]; - continue; - } - } - } - - $product = $this->productMapper->setData($item)->build(); - - $urlRewritesData = $item['url_rewrites'] ?? []; - $urlRewrites = []; - foreach ($urlRewritesData as $urlRewriteData) { - $urlRewrites[] = $this->prepareUrlRewrite($urlRewriteData); - } - - $product->setUrlRewrites($urlRewrites); - $product = $this->setDynamicAttributes($item, $product); - - return $product; - } - /** - * Set dynamic attributes (custom attributes created in admin) to product entity. - * - * @param array $item - * @param \Magento\CatalogStorefrontApi\Api\Data\Product $product - * @return \Magento\CatalogStorefrontApi\Api\Data\Product - */ - private function setDynamicAttributes( - array $item, - \Magento\CatalogStorefrontApi\Api\Data\Product $product - ): \Magento\CatalogStorefrontApi\Api\Data\Product { - $dynamicAttributes = []; - - foreach ($item as $attributeCode => $value) { - $parts = explode('_', $attributeCode); - $parts = array_map("ucfirst", $parts); - $getterMethodName = 'get' . implode('', $parts); - if (\method_exists($product, $getterMethodName)) { - continue; - } - /** @var \Magento\CatalogStorefrontApi\Api\Data\DynamicAttributeValueInterface $dynamicAttribute */ - $dynamicAttribute = $this->dynamicAttributeFactory->create(); - $dynamicAttribute->setCode((string)$attributeCode); - $dynamicAttribute->setValue((string)$value); - $dynamicAttributes[] = $dynamicAttribute; - } - - $product->setDynamicAttributes($dynamicAttributes); - - return $product; - } - - /** - * Prepare Url Rewrite data - * - * @param array $urlRewriteData - * @return UrlRewrite $urlRewriteData - */ - private function prepareUrlRewrite(array $urlRewriteData): UrlRewrite - { - $rewrite = new UrlRewrite; - $rewrite->setUrl($urlRewriteData['url'] ?? ''); - $parameters = []; - foreach ($urlRewriteData['parameters'] ?? [] as $parameterData) { - $parameter = new UrlRewriteParameter; - $parameter->setName($parameterData['name'] ?? ''); - $parameter->setValue($parameterData['value'] ?? ''); - $parameters[] = $parameter; - } - $rewrite->setParameters($parameters); + $result->setItems($items); - return $rewrite; + return $result; } } From 845e4e19de0259c42d328c9a84055e191bb615cb Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko Date: Thu, 15 Oct 2020 09:28:34 -0500 Subject: [PATCH 6/7] SFAPP-102: How to do contribution into available CE projects repositories --- .../How-To-Contribute-To-Project.md | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 dev/docs/contribution/How-To-Contribute-To-Project.md diff --git a/dev/docs/contribution/How-To-Contribute-To-Project.md b/dev/docs/contribution/How-To-Contribute-To-Project.md new file mode 100644 index 000000000..0f9e0df8f --- /dev/null +++ b/dev/docs/contribution/How-To-Contribute-To-Project.md @@ -0,0 +1,51 @@ +Two main points that underlie the following instruction: +1) magento org is a read-only replica of new primary fork visible only to internal teams +2) Sync from that invisible primary fork to magento org happens in eventually consistent way + +The example would be given for complex task that has a code changes for catalog-storefront and saas-export repos but whatever repo of Storefront project you need to contribute the flow will look same. + +## Step #1 +Make a fork of catalog-storefront and saas-export repos from magento org to your own organisation. +## Step #2 [optional] +If you are working together with someone else in a team, please create your story-branch from magento/catalog-storefront/develop branch and push it to your fork. +For example, you need auto-generated files from proto-scheme, then someone from internal magento team would be able to create a PR to your story-branch. +## Step #3 +When you ready, create a PR from your fork to magento/catalog-storefront and magento/saas-export repos + +*Note:* don't forget to link the PRs by providing this information under the _Related Pull Requests_ section +*Examples:* +``` +### Related Pull Requests +https://github.com/magento/saas-export/pull/9999999 + +``` +## Step #4 +Run the tests on github by adding next comment to magento/catalog-storefront PR: +``` +@magento run all tests +``` + +*Note:* if you need to run some specific kind of tests you can add next comment: +``` +@magento run Integration Tests +``` + +*Exception:* if you have changes only to magento2 project for example and don't have any changes to catalog-storefront, that means you have nothing to contribute to catalog-storefront. +It such rarer case you have to create a dummy-PR to catalog-storefront with any changes, but, please put in the begining of Pr's title "[DUMMY-PR]". We would know that this shouldn't be merged. +## Step #5 +When all the tests would be green, please ask someone from internal team to migrate the PR to magento-commerce. + +*Note:* this is the comment that has to appear on all of your PRs you want contribute: +``` +@magento import pr to magento-team/catalog-storefront-ce +or +@magento import code to magento-team/catalog-storefront-ce +``` +It has to be done for each PR. +If the gatekeeper miss any of the PRs, please notify him/her. +## Step #6 +Once changes would be propagated to magento-commerce org they would be visible(eventually) in magento org. +And yes, only after that we will close your PRs with the nice comment that we appreciate your contribution and changes were merged to the main fork of our project. + +*Note:* technically, your PRs would be closed and not merged in regard to magento org forks. That's because our magento/\* forks became a read-only from now. The main fork would be inside another org. You can reason about that as some abstract "Primary fork" and "magento/*" as a replica fork. +Eventually, your commits would be synced to magento/\* fork, and you would be the contributor of those changes, in that regards nothing changed. Only PRs would be displayed as 'Closed' instead of 'Merged'. \ No newline at end of file From 5ccfedcbee1e9325a403d3b6d7791088acd5f53b Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko Date: Thu, 15 Oct 2020 16:39:58 -0500 Subject: [PATCH 7/7] SFAPP-102: How to do contribution into available CE projects repositories --- dev/docs/contribution/How-To-Contribute-To-Project.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/docs/contribution/How-To-Contribute-To-Project.md b/dev/docs/contribution/How-To-Contribute-To-Project.md index 0f9e0df8f..6070aaeed 100644 --- a/dev/docs/contribution/How-To-Contribute-To-Project.md +++ b/dev/docs/contribution/How-To-Contribute-To-Project.md @@ -1,6 +1,6 @@ -Two main points that underlie the following instruction: +Two main points that is underlie the following instruction: 1) magento org is a read-only replica of new primary fork visible only to internal teams -2) Sync from that invisible primary fork to magento org happens in eventually consistent way +2) sync from that invisible primary fork to magento org happens in eventually consistent way The example would be given for complex task that has a code changes for catalog-storefront and saas-export repos but whatever repo of Storefront project you need to contribute the flow will look same.