From 97be4a868c3cc00abf949bcd883c12684a916c62 Mon Sep 17 00:00:00 2001 From: Devesh Chevli Date: Tue, 11 Jul 2017 16:58:10 +0100 Subject: [PATCH 1/4] Start on a component to create product links [ci skip] --- Model/Component/ProductLinks.php | 25 +++++++++++++++++++ .../Components/ProductLinks/cross-sells.yaml | 4 +++ Samples/Components/ProductLinks/related.yaml | 4 +++ Samples/Components/ProductLinks/up-sells.yaml | 4 +++ Samples/master.yaml | 9 ++++++- etc/configurator.xml | 1 + 6 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 Model/Component/ProductLinks.php create mode 100644 Samples/Components/ProductLinks/cross-sells.yaml create mode 100644 Samples/Components/ProductLinks/related.yaml create mode 100644 Samples/Components/ProductLinks/up-sells.yaml diff --git a/Model/Component/ProductLinks.php b/Model/Component/ProductLinks.php new file mode 100644 index 0000000..cdc1920 --- /dev/null +++ b/Model/Component/ProductLinks.php @@ -0,0 +1,25 @@ + + \ No newline at end of file From 1fbd557ed27c5fde92c29af6818cd6fd7ac04bcf Mon Sep 17 00:00:00 2001 From: Devesh Chevli Date: Fri, 14 Jul 2017 16:38:48 +0100 Subject: [PATCH 2/4] Product Links - Related, Cross Sells & Up Sells Component --- Model/Component/ProductLinks.php | 135 +++++++++++++++++- Model/Component/YamlComponentAbstract.php | 2 + README.md | 5 +- .../Components/ProductLinks/cross-sells.yaml | 2 +- Samples/Components/ProductLinks/related.yaml | 2 +- Samples/Components/ProductLinks/up-sells.yaml | 2 +- Test/Unit/Component/ProductLinksTest.php | 15 ++ docs/index.html | 10 +- 8 files changed, 158 insertions(+), 15 deletions(-) create mode 100644 Test/Unit/Component/ProductLinksTest.php diff --git a/Model/Component/ProductLinks.php b/Model/Component/ProductLinks.php index cdc1920..65ac299 100644 --- a/Model/Component/ProductLinks.php +++ b/Model/Component/ProductLinks.php @@ -2,24 +2,147 @@ namespace CtiDigital\Configurator\Model\Component; +use CtiDigital\Configurator\Model\LoggingInterface; +use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Api\Data\ProductLinkInterfaceFactory; +use Magento\Framework\ObjectManagerInterface; +use CtiDigital\Configurator\Model\Exception\ComponentException; class ProductLinks extends YamlComponentAbstract { - protected $alias = 'productlinks'; + protected $alias = 'product_links'; protected $name = 'Product Links'; protected $description = 'Component to create and maintain product links (related/up-sells/cross-sells)'; - public function canParseAndProcess() - { - return parent::canParseAndProcess(); // TODO: Change the autogenerated stub + + // @var Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory + protected $productLinkFactory; + + protected $productRepository; + + protected $allowedLinks = ['relation', 'up_sell', 'cross_sell']; + protected $linkTypeMap = ['relation' => 'related', 'up_sell' => 'upsell', 'cross_sell' => 'crosssell']; + + public function __construct( + LoggingInterface $log, + ObjectManagerInterface $objectManager, + ProductRepositoryInterface $productRepository, + ProductLinkInterfaceFactory $productLinkFactory + ) { + parent::__construct($log, $objectManager); + $this->productRepository = $productRepository; + $this->productLinkFactory = $productLinkFactory; } + /** + * Process the data by splitting up the different link types. + * + * @param $data + */ public function processData($data = null) { - // TODO: Implement processData() method. + try { + + // Loop through all the product link types - if there are multiple link types in the yaml file + foreach ($data as $linkType => $skus) { + + // Validate the link type to see if it is allowed + if (!in_array($linkType, $this->allowedLinks)) { + throw new ComponentException(sprintf('Link type %s is not supported', $linkType)); + } + + // Process creating the links + $this->processSkus($skus, $linkType); + } + } catch (ComponentException $e) { + $this->log->logError($e->getMessage()); + } catch (\Exception $e) { + $this->log->logError($e->getMessage()); + } + } + + /** + * Process an array of products that require products linking to them + * + * @param array $data + * @param $linkType + */ + private function processSkus(array $data, $linkType) + { + try { + + // Loop through the SKUs in the link type + foreach ($data as $sku => $linkSkus) { + + // Check if the product exists + if (!$this->doesProductExist($sku)) { + throw new ComponentException(sprintf('SKU (%s) for products to link to is not found', $sku)); + } + $this->log->logComment(sprintf('Creating product links for %s', $sku)); + + // Process the links for that product + $this->processLinks($sku, $linkSkus, $linkType); + } + } catch (ComponentException $e) { + $this->log->logError($e->getMessage()); + } catch (\Exception $e) { + $this->log->logError($e->getMessage()); + } } + /** + * Process all the SKUs that need to be linked to a particular product (SKU) + * + * @param $sku + * @param $linkSkus + * @param $linkType + */ + private function processLinks($sku, $linkSkus, $linkType) + { + try { + + $productLinks = array(); + + // Loop through all the products that require linking to a product + foreach ($linkSkus as $position => $linkSku) { + + // Check if the product exists + if (!$this->doesProductExist($linkSku)) { + throw new ComponentException(sprintf('SKU (%s) to link does not exist', $linkSku)); + } -} \ No newline at end of file + // Create an array of product link objects + $productLinks[] = $this->productLinkFactory->create()->setSku($sku) + ->setLinkedProductSku($linkSku) + ->setLinkType($this->linkTypeMap[$linkType]) + ->setPosition($position * 10); + $this->log->logComment($linkSku, 1); + } + + // Save product links onto the main product + $this->productRepository->get($sku)->setProductLinks($productLinks)->save(); + $this->log->logComment(sprintf('Saved product links for %s', $sku), 1); + + } catch (ComponentException $e) { + $this->log->logError($e->getMessage(), 1); + } catch (\Exception $e) { + $this->log->logError($e->getMessage(), 1); + } + } + + /** + * Check if the product exists function + * + * @param string $sku + * @return bool + * @todo find an efficient way to check if the product exists. + */ + private function doesProductExist($sku) + { + if ($this->productRepository->get($sku)->getId()) { + return true; + } + return false; + } +} diff --git a/Model/Component/YamlComponentAbstract.php b/Model/Component/YamlComponentAbstract.php index be571e7..a227f44 100644 --- a/Model/Component/YamlComponentAbstract.php +++ b/Model/Component/YamlComponentAbstract.php @@ -12,6 +12,8 @@ * * Abstract Class for Components driven by YAML configuration * @package CtiDigital\Configurator\Model\Component + * + * @SuppressWarnings(PHPMD.NumberOfChildren) */ abstract class YamlComponentAbstract extends ComponentAbstract { diff --git a/README.md b/README.md index 97ca5ce..826e64a 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ These test include PHP Code Sniffer, PHP Mess Detector, PHP Copy and Paste Detec php vendor/bin/phpcs --standard=PSR2 vendor/ctidigital/magento2-configurator/Model/ vendor/ctidigital/magento2-configurator/Console/ vendor/ctidigital/magento2-configurator/Test/ vendor/ctidigital/magento2-configurator/Helper/ php vendor/bin/phpmd vendor/ctidigital/magento2-configurator/Model/,vendor/ctidigital/magento2-configurator/Console/,vendor/ctidigital/magento2-configurator/Test/,vendor/ctidigital/magento2-configurator/Helper/ text cleancode,codesize,controversial,design,naming,unusedcode php vendor/bin/phpcpd vendor/ctidigital/magento2-configurator/Model/ vendor/ctidigital/magento2-configurator/Console vendor/ctidigital/magento2-configurator/Test/ vendor/ctidigital/magento2-configurator/Helper/ -php vendor/bin/phpunit --coverage-clover build/logs/clover.xml vendor/ctidigital/magento2-configurator/Test/Unit/ +php vendor/bin/phpunit vendor/ctidigital/magento2-configurator/Test/Unit/ ``` ## Integration tests @@ -92,6 +92,9 @@ It tests the following: | Tax Rates | :white_check_mark: | :grey_exclamation: | :white_check_mark: | | Rewrites | :white_check_mark: | :white_check_mark: | :white_check_mark: | | Review Ratings | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Related Products | :white_check_mark: | :grey_exclamation: | :white_check_mark: | +| Up Sell Products | :white_check_mark: | :grey_exclamation: | :white_check_mark: | +| Cross Sell Products | :white_check_mark: | :grey_exclamation: | :white_check_mark: | | Customers | :x: | :x: | :x: | | Related Products | :x: | :x: | :x: | | SQL | :x: | :x: | :x: | diff --git a/Samples/Components/ProductLinks/cross-sells.yaml b/Samples/Components/ProductLinks/cross-sells.yaml index 8a00d4b..cb54a56 100644 --- a/Samples/Components/ProductLinks/cross-sells.yaml +++ b/Samples/Components/ProductLinks/cross-sells.yaml @@ -1,4 +1,4 @@ -cross-sells: +cross_sell: configurable_product_2: - simple-product - configurable_product_1 \ No newline at end of file diff --git a/Samples/Components/ProductLinks/related.yaml b/Samples/Components/ProductLinks/related.yaml index ad1f355..7192173 100644 --- a/Samples/Components/ProductLinks/related.yaml +++ b/Samples/Components/ProductLinks/related.yaml @@ -1,4 +1,4 @@ -related: +relation: simple-product: - configurable_product_1 - configurable_product_2 \ No newline at end of file diff --git a/Samples/Components/ProductLinks/up-sells.yaml b/Samples/Components/ProductLinks/up-sells.yaml index 14d86cf..a25f808 100644 --- a/Samples/Components/ProductLinks/up-sells.yaml +++ b/Samples/Components/ProductLinks/up-sells.yaml @@ -1,4 +1,4 @@ -up-sells: +up_sell: configurable_product_1: - simple-product - configurable_product_2 \ No newline at end of file diff --git a/Test/Unit/Component/ProductLinksTest.php b/Test/Unit/Component/ProductLinksTest.php new file mode 100644 index 0000000..74814fe --- /dev/null +++ b/Test/Unit/Component/ProductLinksTest.php @@ -0,0 +1,15 @@ +component = $this->testObjectManager->getObject('CtiDigital\Configurator\Model\Component\ProductLinks'); + $this->className = ProductLinks::class; + } +} diff --git a/docs/index.html b/docs/index.html index 913c7c3..725d13b 100644 --- a/docs/index.html +++ b/docs/index.html @@ -178,11 +178,15 @@

Supported Components

Customer Groups +
  • + + Product Links Related, Up-sells & Cross-sells +
  • Media
  • -
  • +
  • Tax Rules & Rates
  • @@ -199,10 +203,6 @@

    Work In Progress Components

    Below are the list of components, not supported and been worked upon.

      -
    • - - Related Products -
    • Customers From 9bb0ba23f4124886d2d6e1787950298829b22da1 Mon Sep 17 00:00:00 2001 From: Devesh Chevli Date: Fri, 14 Jul 2017 16:49:20 +0100 Subject: [PATCH 3/4] Bump Configurator Version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a26aa72..e0934b8 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "satooshi/php-coveralls": "^1.0", "phpunit/phpunit": "4.1.0" }, - "version": "0.18.0-dev", + "version": "0.19.0-dev", "autoload": { "files": [ "registration.php" ], "psr-4": { From 9a294b8cf253b5a1ed873f8843437e7d7a3fa234 Mon Sep 17 00:00:00 2001 From: Devesh Chevli Date: Fri, 14 Jul 2017 16:55:14 +0100 Subject: [PATCH 4/4] Alter logging for product links --- Model/Component/ProductLinks.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Model/Component/ProductLinks.php b/Model/Component/ProductLinks.php index 65ac299..7ef4f01 100644 --- a/Model/Component/ProductLinks.php +++ b/Model/Component/ProductLinks.php @@ -79,7 +79,7 @@ private function processSkus(array $data, $linkType) if (!$this->doesProductExist($sku)) { throw new ComponentException(sprintf('SKU (%s) for products to link to is not found', $sku)); } - $this->log->logComment(sprintf('Creating product links for %s', $sku)); + $this->log->logInfo(sprintf('Creating product links for %s', $sku)); // Process the links for that product $this->processLinks($sku, $linkSkus, $linkType); @@ -117,7 +117,7 @@ private function processLinks($sku, $linkSkus, $linkType) ->setLinkedProductSku($linkSku) ->setLinkType($this->linkTypeMap[$linkType]) ->setPosition($position * 10); - $this->log->logComment($linkSku, 1); + $this->log->logInfo($linkSku, 1); } // Save product links onto the main product