From 4ec34fc883225a51a09b135781ea80ad611bef95 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 8 Nov 2019 16:16:43 +0000 Subject: [PATCH 01/51] Allow a remote source to be defined. Add support for JSON files. Detect the file format. --- Component/AdminRoles.php | 6 +- Component/AdminUsers.php | 6 +- Component/ApiIntegrations.php | 2 + Component/AttributeSets.php | 6 +- Component/Attributes.php | 9 +- Component/Blocks.php | 6 +- Component/CatalogPriceRules.php | 6 +- Component/Categories.php | 6 +- Component/ComponentAbstract.php | 124 +++++++++++++++++- Component/Config.php | 6 +- Component/CsvComponentAbstract.php | 57 -------- Component/CustomerAttributes.php | 4 +- Component/CustomerGroups.php | 6 +- Component/Customers.php | 6 +- Component/Media.php | 6 +- Component/Pages.php | 4 +- Component/ProductLinks.php | 4 +- Component/Products.php | 6 +- Component/ReviewRating.php | 6 +- Component/Rewrites.php | 6 +- Component/ShippingTableRates.php | 6 +- Component/Sql.php | 6 +- Component/TaxRates.php | 6 +- Component/TaxRules.php | 6 +- Component/TieredPrices.php | 6 +- Component/Websites.php | 6 +- Component/Widgets.php | 6 +- Component/YamlComponentAbstract.php | 63 --------- .../Component/ComponentAbstractTestCase.php | 23 ++++ 29 files changed, 238 insertions(+), 172 deletions(-) delete mode 100644 Component/CsvComponentAbstract.php delete mode 100644 Component/YamlComponentAbstract.php diff --git a/Component/AdminRoles.php b/Component/AdminRoles.php index 35195d4..6213555 100644 --- a/Component/AdminRoles.php +++ b/Component/AdminRoles.php @@ -2,6 +2,7 @@ namespace CtiDigital\Configurator\Component; use Magento\Authorization\Model\RoleFactory; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\ObjectManagerInterface; use Magento\Authorization\Model\RulesFactory; use CtiDigital\Configurator\Api\LoggerInterface; @@ -9,7 +10,7 @@ use Magento\Authorization\Model\Acl\Role\Group as RoleGroup; use CtiDigital\Configurator\Exception\ComponentException; -class AdminRoles extends YamlComponentAbstract +class AdminRoles extends ComponentAbstract { protected $alias = 'adminroles'; protected $name = 'Admin Roles'; @@ -39,10 +40,11 @@ class AdminRoles extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, RoleFactory $roleFactory, RulesFactory $rulesFactory ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->roleFactory = $roleFactory; $this->rulesFactory = $rulesFactory; diff --git a/Component/AdminUsers.php b/Component/AdminUsers.php index 3e17ccd..ccac743 100644 --- a/Component/AdminUsers.php +++ b/Component/AdminUsers.php @@ -2,13 +2,14 @@ namespace CtiDigital\Configurator\Component; use Symfony\Component\Yaml\Yaml; +use Magento\Framework\Serialize\Serializer\Json; use Magento\User\Model\UserFactory; use Magento\Authorization\Model\RoleFactory; use Magento\Framework\ObjectManagerInterface; use CtiDigital\Configurator\Api\LoggerInterface; use CtiDigital\Configurator\Exception\ComponentException; -class AdminUsers extends YamlComponentAbstract +class AdminUsers extends ComponentAbstract { protected $alias = 'adminusers'; protected $name = 'Admin Users'; @@ -38,10 +39,11 @@ class AdminUsers extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, UserFactory $userFactory, RoleFactory $roleFactory ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->userFactory = $userFactory; $this->roleFactory = $roleFactory; diff --git a/Component/ApiIntegrations.php b/Component/ApiIntegrations.php index 06907b7..4f92673 100644 --- a/Component/ApiIntegrations.php +++ b/Component/ApiIntegrations.php @@ -2,6 +2,7 @@ namespace CtiDigital\Configurator\Component; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Integration\Model\IntegrationFactory; use Magento\Integration\Model\Oauth\TokenFactory; use CtiDigital\Configurator\Api\LoggerInterface; @@ -47,6 +48,7 @@ class ApiIntegrations extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, IntegrationFactory $integrationFactory, IntegrationServiceInterface $integrationService, AuthorizationService $authorizationService, diff --git a/Component/AttributeSets.php b/Component/AttributeSets.php index 16ac00b..e072625 100644 --- a/Component/AttributeSets.php +++ b/Component/AttributeSets.php @@ -3,6 +3,7 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Exception\ComponentException; +use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Eav\Api\AttributeSetRepositoryInterface; use Magento\Catalog\Model\Product; @@ -16,7 +17,7 @@ * @package CtiDigital\Configurator\Model\Component * @SuppressWarnings(PHPMD.LongVariable) */ -class AttributeSets extends YamlComponentAbstract +class AttributeSets extends ComponentAbstract { protected $alias = 'attribute_sets'; protected $name = 'Attribute Sets'; @@ -42,11 +43,12 @@ class AttributeSets extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, EavSetup $eavSetup, AttributeSetRepositoryInterface $attributeSetRepository ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->eavSetup = $eavSetup; $this->attributeSetRepository = $attributeSetRepository; diff --git a/Component/Attributes.php b/Component/Attributes.php index d98be92..6313e80 100644 --- a/Component/Attributes.php +++ b/Component/Attributes.php @@ -3,6 +3,7 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Exception\ComponentException; +use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Catalog\Model\Product; use Magento\Eav\Api\AttributeRepositoryInterface; @@ -15,7 +16,7 @@ * @package CtiDigital\Configurator\Model\Component * @SuppressWarnings(PHPMD.LongVariable) */ -class Attributes extends YamlComponentAbstract +class Attributes extends ComponentAbstract { protected $alias = 'attributes'; @@ -77,10 +78,11 @@ class Attributes extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, EavSetup $eavSetup, AttributeRepositoryInterface $attributeRepository ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->eavSetup = $eavSetup; $this->attributeRepository = $attributeRepository; } @@ -115,9 +117,6 @@ protected function processAttribute($attributeCode, array $attributeConfig) if (isset($attributeConfig['option'])) { $newAttributeOptions = $this->manageAttributeOptions($attributeCode, $attributeConfig['option']); - if (!empty($newAttributeOptions)) { - $updateAttribute = true; - } $attributeConfig['option']['values'] = $newAttributeOptions; } } diff --git a/Component/Blocks.php b/Component/Blocks.php index 5af4ebb..3ce61fe 100644 --- a/Component/Blocks.php +++ b/Component/Blocks.php @@ -3,11 +3,12 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Exception\ComponentException; +use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Cms\Api\Data\BlockInterfaceFactory; use Magento\Framework\ObjectManagerInterface; -class Blocks extends YamlComponentAbstract +class Blocks extends ComponentAbstract { protected $alias = 'blocks'; @@ -38,9 +39,10 @@ class Blocks extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, BlockInterfaceFactory $blockFactory ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->blockFactory = $blockFactory; $this->storeManager = $this->objectManager->create(\Magento\Store\Model\Store::class); diff --git a/Component/CatalogPriceRules.php b/Component/CatalogPriceRules.php index 3e9c802..d2c44b9 100644 --- a/Component/CatalogPriceRules.php +++ b/Component/CatalogPriceRules.php @@ -8,6 +8,7 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Api\ComponentProcessorInterface; +use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\CatalogRule\Api\Data\RuleInterfaceFactory; use Magento\Framework\ObjectManagerInterface; @@ -15,7 +16,7 @@ /** * Class CatalogPriceRules */ -class CatalogPriceRules extends YamlComponentAbstract +class CatalogPriceRules extends ComponentAbstract { /** * @var string @@ -47,9 +48,10 @@ class CatalogPriceRules extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, ComponentProcessorInterface $processor ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->processor = $processor; } diff --git a/Component/Categories.php b/Component/Categories.php index 89b6ea6..ba7bafa 100644 --- a/Component/Categories.php +++ b/Component/Categories.php @@ -3,10 +3,11 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Exception\ComponentException; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\Webapi\Exception; use Symfony\Component\Yaml\Yaml; -class Categories extends YamlComponentAbstract +class Categories extends ComponentAbstract { protected $alias = 'categories'; protected $name = 'Categories'; @@ -24,6 +25,7 @@ class Categories extends YamlComponentAbstract public function __construct( \CtiDigital\Configurator\Api\LoggerInterface $log, \Magento\Framework\ObjectManagerInterface $objectManager, + Json $json, \Magento\Catalog\Model\CategoryFactory $category, \Magento\Store\Model\GroupFactory $groupFactory, \Magento\Framework\App\Filesystem\DirectoryList $dirList @@ -31,7 +33,7 @@ public function __construct( $this->category = $category; $this->groupFactory = $groupFactory; $this->dirList = $dirList; - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); } public function processData($data = null) diff --git a/Component/ComponentAbstract.php b/Component/ComponentAbstract.php index 1fed656..83f72fd 100644 --- a/Component/ComponentAbstract.php +++ b/Component/ComponentAbstract.php @@ -4,14 +4,21 @@ use CtiDigital\Configurator\Exception\ComponentException; use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\Framework\File\Csv; +use Magento\Framework\Filesystem\Driver\File; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Serialize\Serializer\Json; +use Symfony\Component\Yaml\Yaml; abstract class ComponentAbstract { - const ENABLED = 1; const DISABLED = 0; + const SOURCE_YAML = 'yaml'; + const SOURCE_CSV = 'csv'; + const SOURCE_JSON = 'json'; + protected $log; protected $alias; protected $name; @@ -20,12 +27,19 @@ abstract class ComponentAbstract protected $objectManager; protected $description = 'Unknown Component'; + /** + * @var Json + */ + protected $json; + public function __construct( LoggerInterface $log, - ObjectManagerInterface $objectManager + ObjectManagerInterface $objectManager, + Json $json ) { $this->log = $log; $this->objectManager = $objectManager; + $this->json = $json; } /** @@ -110,6 +124,28 @@ public function process() } } + /** + * @return true + */ + public function isSourceRemote($source) + { + return (filter_var($source, FILTER_VALIDATE_URL) !== false) ? true : false; + } + + /** + * @param $source + * @return array|bool|float|int|mixed|string|null + * @throws \Exception + */ + public function getRemoteData($source) + { + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $streamContext = stream_context_create(['ssl' => ['verify_peer' => false, 'verify_peer_name' => false]]); + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $remoteFile = file_get_contents($source, false, $streamContext); + return $remoteFile; + } + /** * This method is used to check whether the data from file or a third party * can be parsed and processed. (e.g. does a YAML file exist for it?) @@ -118,7 +154,17 @@ public function process() * * @return bool */ - abstract protected function canParseAndProcess(); + protected function canParseAndProcess() + { + $path = BP . '/' . $this->source; + // phpcs:ignore Magento2.Functions.DiscouragedFunction + if ($this->isSourceRemote($this->source) === false && !file_exists($path)) { + throw new ComponentException( + sprintf("Could not find file in path %s", $path) + ); + } + return true; + } /** * Whether it be from many files or an external database, parsing (pre-processing) @@ -127,7 +173,77 @@ abstract protected function canParseAndProcess(); * @param $source * @return mixed */ - abstract protected function parseData($source = null); + protected function parseData($source = null) + { + $ext = $this->getExtension($source); + if ($this->isSourceRemote($source)) { + $source = $this->getRemoteData($source); + } + if ($ext === self::SOURCE_YAML) { + return $this->parseYamlData($source); + } + if ($ext === self::SOURCE_CSV) { + return $this->parseCsvData($source); + } + if ($ext === self::SOURCE_JSON) { + return $this->parseJsonData($source); + } + } + + /** + * @param $source + * @return string + * @throws \Exception + */ + private function getExtension($source) + { + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $extension = pathinfo($source, PATHINFO_EXTENSION); + if (strtolower($extension) === 'yaml') { + return self::SOURCE_YAML; + } + if (strtolower($extension) === 'csv') { + return self::SOURCE_CSV; + } + if (strtolower($extension) === 'json') { + return self::SOURCE_JSON; + } + throw new ComponentException(sprintf('Source "%s" does not have a valid file extension.', $source)); + } + + /** + * @param $source + * @return mixed + */ + private function parseYamlData($source) + { + $path = BP . '/' . $source; + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $data = file_get_contents($path); + return (new Yaml())->parse($data); + } + + /** + * @param $source + * @return array + * @throws \Exception + */ + private function parseCsvData($source) + { + $file = new File(); + $parser = new Csv($file); + + return $parser->getData($source); + } + + /** + * @param $source + * @return array|bool|float|int|mixed|string|null + */ + private function parseJsonData($source) + { + return $jsonData = $this->json->unserialize($source); + } /** * This method should be used to process the data and populate the Magento Database. diff --git a/Component/Config.php b/Component/Config.php index 5d2e5c8..28b7026 100644 --- a/Component/Config.php +++ b/Component/Config.php @@ -11,8 +11,9 @@ use Magento\Theme\Model\ResourceModel\Theme\Collection; use Magento\Theme\Model\ResourceModel\Theme\CollectionFactory; use Symfony\Component\Yaml\Yaml; +use Magento\Framework\Serialize\Serializer\Json; -class Config extends YamlComponentAbstract +class Config extends ComponentAbstract { const PATH_THEME_ID = 'design/theme/theme_id'; @@ -50,10 +51,11 @@ class Config extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, CollectionFactory $collectionFactory, EncryptorInterface $encryptor ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->configResource = $this->objectManager->create(\Magento\Config\Model\ResourceModel\Config::class); $this->scopeConfig = $this->objectManager->create(\Magento\Framework\App\Config::class); diff --git a/Component/CsvComponentAbstract.php b/Component/CsvComponentAbstract.php deleted file mode 100644 index 1c593a1..0000000 --- a/Component/CsvComponentAbstract.php +++ /dev/null @@ -1,57 +0,0 @@ -source; - if (!file_exists($path)) { - throw new ComponentException( - sprintf("Could not find file in path %s", $path) - ); - } - return true; - } - - /** - * Convert CSV to array - * @param null $source - * @return array - */ - protected function parseData($source = null) - { - try { - if ($source == null) { - throw new ComponentException( - sprintf('The %s component requires to have a file source definition.', $this->alias) - ); - } - - $file = new File(); - $parser = new Csv($file); - - return $parser->getData($source); - } catch (ComponentException $e) { - $this->log->logError($e->getMessage()); - } - - return null; - } -} diff --git a/Component/CustomerAttributes.php b/Component/CustomerAttributes.php index 0d3cb34..54e720c 100644 --- a/Component/CustomerAttributes.php +++ b/Component/CustomerAttributes.php @@ -3,6 +3,7 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Exception\ComponentException; use Magento\Customer\Model\Customer; use Magento\Eav\Setup\EavSetup; @@ -63,6 +64,7 @@ class CustomerAttributes extends Attributes public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, EavSetup $eavSetup, AttributeRepository $attributeRepository, CustomerSetupFactory $customerSetupFactory, @@ -71,7 +73,7 @@ public function __construct( $this->attributeConfigMap = array_merge($this->attributeConfigMap, $this->customerConfigMap); $this->customerSetup = $customerSetupFactory; $this->attributeResource = $attributeResource; - parent::__construct($log, $objectManager, $eavSetup, $attributeRepository); + parent::__construct($log, $objectManager, $json, $eavSetup, $attributeRepository); } /** diff --git a/Component/CustomerGroups.php b/Component/CustomerGroups.php index ba8b32e..a54fd7f 100644 --- a/Component/CustomerGroups.php +++ b/Component/CustomerGroups.php @@ -2,13 +2,14 @@ namespace CtiDigital\Configurator\Component; use Symfony\Component\Yaml\Yaml; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Customer\Model\GroupFactory; use Magento\Tax\Model\ClassModelFactory; use Magento\Framework\ObjectManagerInterface; use CtiDigital\Configurator\Exception\ComponentException; use CtiDigital\Configurator\Api\LoggerInterface; -class CustomerGroups extends YamlComponentAbstract +class CustomerGroups extends ComponentAbstract { protected $alias = 'customergroups'; protected $name = 'Customer Groups'; @@ -35,10 +36,11 @@ class CustomerGroups extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, GroupFactory $groupFactory, ClassModelFactory $classModelFactory ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->groupFactory = $groupFactory; $this->classModelFactory = $classModelFactory; diff --git a/Component/Customers.php b/Component/Customers.php index 6bb51e8..c16cd60 100644 --- a/Component/Customers.php +++ b/Component/Customers.php @@ -2,6 +2,7 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Exception\ComponentException; use Magento\Framework\ObjectManagerInterface; use FireGento\FastSimpleImport\Model\ImporterFactory; @@ -10,7 +11,7 @@ use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Customer\Api\GroupManagementInterface; -class Customers extends CsvComponentAbstract +class Customers extends ComponentAbstract { const CUSTOMER_EMAIL_HEADER = 'email'; const CUSTOMER_GROUP_HEADER = 'group_id'; @@ -68,6 +69,7 @@ class Customers extends CsvComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, ImporterFactory $importerFactory, GroupRepositoryInterface $groupRepository, GroupManagementInterface $groupManagement, @@ -79,7 +81,7 @@ public function __construct( $this->groupManagement = $groupManagement; $this->criteriaBuilder = $criteriaBuilder; $this->indexerFactory = $indexerFactory; - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); } /** diff --git a/Component/Media.php b/Component/Media.php index a23b904..3404861 100644 --- a/Component/Media.php +++ b/Component/Media.php @@ -3,11 +3,12 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Exception\ComponentException; +use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\ObjectManagerInterface; -class Media extends YamlComponentAbstract +class Media extends ComponentAbstract { const FULL_ACCESS = 0777; @@ -20,9 +21,10 @@ class Media extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, DirectoryList $directoryList ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->directoryList = $directoryList; } diff --git a/Component/Pages.php b/Component/Pages.php index 570ac2a..c5f7a23 100644 --- a/Component/Pages.php +++ b/Component/Pages.php @@ -3,6 +3,7 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Exception\ComponentException; +use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Cms\Api\Data\PageInterfaceFactory; use Magento\Cms\Api\PageRepositoryInterface; @@ -51,6 +52,7 @@ class Pages extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, PageRepositoryInterface $pageRepository, PageInterfaceFactory $pageFactory, StoreRepositoryInterface $storeRepository @@ -59,7 +61,7 @@ public function __construct( $this->pageRepository = $pageRepository; $this->storeRepository = $storeRepository; - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); } diff --git a/Component/ProductLinks.php b/Component/ProductLinks.php index fd7f6c7..f7bd3fe 100644 --- a/Component/ProductLinks.php +++ b/Component/ProductLinks.php @@ -3,12 +3,13 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Api\Data\ProductLinkInterfaceFactory; use Magento\Framework\ObjectManagerInterface; use CtiDigital\Configurator\Exception\ComponentException; -class ProductLinks extends YamlComponentAbstract +class ProductLinks extends ComponentAbstract { protected $alias = 'product_links'; @@ -27,6 +28,7 @@ class ProductLinks extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, ProductRepositoryInterface $productRepository, ProductLinkInterfaceFactory $productLinkFactory ) { diff --git a/Component/Products.php b/Component/Products.php index d024ba5..57e3389 100644 --- a/Component/Products.php +++ b/Component/Products.php @@ -2,6 +2,7 @@ namespace CtiDigital\Configurator\Component; use Magento\Catalog\Model\ProductFactory; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\ObjectManagerInterface; use CtiDigital\Configurator\Api\LoggerInterface; use CtiDigital\Configurator\Component\Product\Image; @@ -15,7 +16,7 @@ * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Products extends CsvComponentAbstract +class Products extends ComponentAbstract { const SKU_COLUMN_HEADING = 'sku'; const QTY_COLUMN_HEADING = 'qty'; @@ -102,12 +103,13 @@ class Products extends CsvComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, ImporterFactory $importerFactory, ProductFactory $productFactory, Image $image, AttributeOption $attributeOption ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->productFactory= $productFactory; $this->importerFactory = $importerFactory; $this->image = $image; diff --git a/Component/ReviewRating.php b/Component/ReviewRating.php index b477aed..c52e03a 100644 --- a/Component/ReviewRating.php +++ b/Component/ReviewRating.php @@ -2,6 +2,7 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\ObjectManagerInterface; use Magento\Review\Model\Rating; use Magento\Review\Model\RatingFactory; @@ -17,7 +18,7 @@ * * @SuppressWarnings("CouplingBetweenObjects") */ -class ReviewRating extends YamlComponentAbstract +class ReviewRating extends ComponentAbstract { const MAX_NUM_RATINGS = 5; @@ -50,6 +51,7 @@ class ReviewRating extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, RatingFactory $ratingFactory, StoreRepositoryInterface $storeRepository, OptionFactory $optionFactory, @@ -59,7 +61,7 @@ public function __construct( $this->storeRepository = $storeRepository; $this->optionFactory = $optionFactory; $this->entityFactory = $entityFactory; - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); } public function processData($data = null) diff --git a/Component/Rewrites.php b/Component/Rewrites.php index 8665d7c..3bd2302 100644 --- a/Component/Rewrites.php +++ b/Component/Rewrites.php @@ -3,12 +3,13 @@ namespace CtiDigital\Configurator\Component; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Serialize\Serializer\Json; use Magento\UrlRewrite\Model\UrlRewriteFactory; use Magento\UrlRewrite\Model\UrlPersistInterface; use CtiDigital\Configurator\Exception\ComponentException; use CtiDigital\Configurator\Api\LoggerInterface; -class Rewrites extends CsvComponentAbstract +class Rewrites extends ComponentAbstract { protected $alias = "rewrites"; protected $name = "rewrites"; @@ -43,10 +44,11 @@ class Rewrites extends CsvComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, UrlPersistInterface $urlPersist, UrlRewriteFactory $urlRewriteFactory ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->urlPersist = $urlPersist; $this->urlRewriteFactory = $urlRewriteFactory; } diff --git a/Component/ShippingTableRates.php b/Component/ShippingTableRates.php index 861ad98..c2060b2 100644 --- a/Component/ShippingTableRates.php +++ b/Component/ShippingTableRates.php @@ -2,6 +2,7 @@ namespace CtiDigital\Configurator\Component; use Symfony\Component\Yaml\Yaml; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\ObjectManagerInterface; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Authorization\Model\UserContextInterface; @@ -12,7 +13,7 @@ use Magento\Directory\Model\RegionFactory; use Magento\Directory\Model\Region; -class ShippingTableRates extends YamlComponentAbstract +class ShippingTableRates extends ComponentAbstract { protected $alias = "shippingtablerates"; protected $name = "Shipping Table Rates"; @@ -44,11 +45,12 @@ class ShippingTableRates extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, TablerateFactory $tablerateFactory, WebsiteFactory $websiteFactory, RegionFactory $regionFactory ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->tablerateFactory = $tablerateFactory; $this->websiteFactory = $websiteFactory; $this->regionFactory = $regionFactory; diff --git a/Component/Sql.php b/Component/Sql.php index 44a0ddc..b6aa988 100644 --- a/Component/Sql.php +++ b/Component/Sql.php @@ -8,6 +8,7 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Component\Processor\SqlSplitProcessor; use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Adapter\AdapterInterface; @@ -16,7 +17,7 @@ /** * Class Sql */ -class Sql extends YamlComponentAbstract +class Sql extends ComponentAbstract { /** * @var string @@ -48,9 +49,10 @@ class Sql extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, SqlSplitProcessor $processor ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->processor = $processor; } diff --git a/Component/TaxRates.php b/Component/TaxRates.php index 9f9bae0..18c3d21 100755 --- a/Component/TaxRates.php +++ b/Component/TaxRates.php @@ -3,11 +3,12 @@ namespace CtiDigital\Configurator\Component; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\TaxImportExport\Model\Rate\CsvImportHandler; use CtiDigital\Configurator\Exception\ComponentException; -class TaxRates extends CsvComponentAbstract +class TaxRates extends ComponentAbstract { protected $alias = 'taxrates'; protected $name = 'Tax Rates'; @@ -27,9 +28,10 @@ class TaxRates extends CsvComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, CsvImportHandler $csvImportHandler ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->csvImportHandler = $csvImportHandler; } diff --git a/Component/TaxRules.php b/Component/TaxRules.php index b2a2d08..e796e44 100644 --- a/Component/TaxRules.php +++ b/Component/TaxRules.php @@ -3,13 +3,14 @@ namespace CtiDigital\Configurator\Component; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Tax\Model\Calculation\RuleFactory; use Magento\Tax\Model\Calculation\RateFactory; use Magento\Tax\Model\ClassModelFactory; use CtiDigital\Configurator\Exception\ComponentException; -class TaxRules extends CsvComponentAbstract +class TaxRules extends ComponentAbstract { protected $alias = 'taxrules'; protected $name = 'Tax Rules'; @@ -51,11 +52,12 @@ class TaxRules extends CsvComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, RateFactory $rateFactory, ClassModelFactory $classModelFactory, RuleFactory $ruleFactory ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->rateFactory = $rateFactory; $this->classModelFactory = $classModelFactory; $this->ruleFactory = $ruleFactory; diff --git a/Component/TieredPrices.php b/Component/TieredPrices.php index bcbb392..82170dc 100644 --- a/Component/TieredPrices.php +++ b/Component/TieredPrices.php @@ -3,6 +3,7 @@ namespace CtiDigital\Configurator\Component; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use CtiDigital\Configurator\Component\Product\AttributeOption; use FireGento\FastSimpleImport\Model\ImporterFactory; @@ -14,7 +15,7 @@ * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class TieredPrices extends CsvComponentAbstract +class TieredPrices extends ComponentAbstract { const SKU_COLUMN_HEADING = 'sku'; const SEPARATOR = ';'; @@ -59,10 +60,11 @@ class TieredPrices extends CsvComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, ImporterFactory $importerFactory, AttributeOption $attributeOption ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->importerFactory = $importerFactory; $this->attributeOption = $attributeOption; } diff --git a/Component/Websites.php b/Component/Websites.php index 47bd5ca..e2416fa 100644 --- a/Component/Websites.php +++ b/Component/Websites.php @@ -3,6 +3,7 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\ObjectManagerInterface; use CtiDigital\Configurator\Exception\ComponentException; use Magento\Store\Model\Group; @@ -15,7 +16,7 @@ use Magento\Framework\Event\ManagerInterface; use Symfony\Component\Yaml\Yaml; -class Websites extends YamlComponentAbstract +class Websites extends ComponentAbstract { protected $alias = 'websites'; @@ -46,13 +47,14 @@ class Websites extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, IndexerFactory $indexerFactory, ManagerInterface $eventManager, WebsiteFactory $websiteFactory, StoreFactory $storeFactory, GroupFactory $groupFactory ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->indexer = $indexerFactory; $this->eventManager = $eventManager; diff --git a/Component/Widgets.php b/Component/Widgets.php index 3e76abc..af57c12 100644 --- a/Component/Widgets.php +++ b/Component/Widgets.php @@ -3,13 +3,14 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\ObjectManagerInterface; use CtiDigital\Configurator\Exception\ComponentException; use Magento\Widget\Model\ResourceModel\Widget\Instance\Collection as WidgetCollection; use Magento\Theme\Model\ResourceModel\Theme\Collection as ThemeCollection; use Magento\Store\Model\StoreFactory; -class Widgets extends YamlComponentAbstract +class Widgets extends ComponentAbstract { protected $alias = 'widgets'; @@ -22,11 +23,12 @@ class Widgets extends YamlComponentAbstract public function __construct( LoggerInterface $log, ObjectManagerInterface $objectManager, + Json $json, WidgetCollection $collection, StoreFactory $storeFactory, ThemeCollection $themeCollection ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->widgetCollection = $collection; $this->themeCollection = $themeCollection; $this->storeFactory = $storeFactory; diff --git a/Component/YamlComponentAbstract.php b/Component/YamlComponentAbstract.php deleted file mode 100644 index bb6c7fd..0000000 --- a/Component/YamlComponentAbstract.php +++ /dev/null @@ -1,63 +0,0 @@ -source; - if (!file_exists($path)) { - throw new ComponentException( - sprintf("Could not find file in path %s", $path) - ); - } - return true; - } - - - /** - * Convert YAML to array - * - * @param null $source - * @return mixed - */ - protected function parseData($source = null) - { - try { - if ($source == null) { - throw new ComponentException( - sprintf('The %s component requires to have a file source definition.', $this->alias) - ); - } - - $path = BP . '/' . $source; - $data = file_get_contents($path); - return (new Yaml())->parse($data); - } catch (ParseException $e) { - throw new ComponentException( - sprintf('The %s component failed to parse. Error: %s.', $source, $e->getMessage()) - ); - } catch (ComponentException $e) { - $this->log->logError($e->getMessage()); - } - } -} diff --git a/Test/Unit/Component/ComponentAbstractTestCase.php b/Test/Unit/Component/ComponentAbstractTestCase.php index c53851c..c0c2c66 100644 --- a/Test/Unit/Component/ComponentAbstractTestCase.php +++ b/Test/Unit/Component/ComponentAbstractTestCase.php @@ -66,4 +66,27 @@ public function testItHasAName() sprintf('No name specified in component %s', $this->className) ); } + + /** + * @param $testSource + * @param $expected + * + * @dataProvider isSourceRemoteDataProvider + */ + public function testIsSourceRemote($testSource, $expected) + { + $this->assertEquals($expected, $this->component->isSourceRemote($testSource)); + } + + /** + * @return array + */ + public static function isSourceRemoteDataProvider() + { + return [ + ['https://www.test.com/remote-source.json', true], + ['../configurator/Configuration/base-website-config.yaml', false], + ['configurator/Configuration/example.csv', false] + ]; + } } From 6a25db93f241f06ef8c78ed72130299ae00f1ad7 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 8 Nov 2019 16:23:54 +0000 Subject: [PATCH 02/51] Fix missing parameter in constructor. --- Component/ApiIntegrations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Component/ApiIntegrations.php b/Component/ApiIntegrations.php index 4f92673..1aeaeb5 100644 --- a/Component/ApiIntegrations.php +++ b/Component/ApiIntegrations.php @@ -54,7 +54,7 @@ public function __construct( AuthorizationService $authorizationService, TokenFactory $tokenFactory ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->integrationFactory = $integrationFactory; $this->integrationService = $integrationService; From 5bd7044f0fb9f74883887214810e197984294399 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 29 Nov 2019 10:00:36 +0000 Subject: [PATCH 03/51] Fix Components. --- Component/ApiIntegrations.php | 2 +- Component/Pages.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Component/ApiIntegrations.php b/Component/ApiIntegrations.php index 1aeaeb5..8ebb0f4 100644 --- a/Component/ApiIntegrations.php +++ b/Component/ApiIntegrations.php @@ -10,7 +10,7 @@ use Magento\Integration\Api\IntegrationServiceInterface; use CtiDigital\Configurator\Exception\ComponentException; -class ApiIntegrations extends YamlComponentAbstract +class ApiIntegrations extends ComponentAbstract { protected $alias = 'apiintegrations'; protected $name = 'Api Integrations'; diff --git a/Component/Pages.php b/Component/Pages.php index c5f7a23..c72d546 100644 --- a/Component/Pages.php +++ b/Component/Pages.php @@ -18,7 +18,7 @@ * * @package CtiDigital\Configurator\Model\Component */ -class Pages extends YamlComponentAbstract +class Pages extends ComponentAbstract { protected $alias = 'pages'; protected $name = 'Pages'; From ebd3e78a0c450c7cede788262939324c1b5d21c5 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 29 Nov 2019 10:27:25 +0000 Subject: [PATCH 04/51] Create a method to get the data from the source. --- Component/ComponentAbstract.php | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Component/ComponentAbstract.php b/Component/ComponentAbstract.php index 83f72fd..15547bb 100644 --- a/Component/ComponentAbstract.php +++ b/Component/ComponentAbstract.php @@ -132,6 +132,18 @@ public function isSourceRemote($source) return (filter_var($source, FILTER_VALIDATE_URL) !== false) ? true : false; } + /** + * @param $source + * @return array|bool|false|float|int|mixed|string|null + * @throws \Exception + */ + private function getData($source) + { + return ($this->isSourceRemote($source) === true) ? + $this->getRemoteData($source) : + file_get_contents(BP . '/' . $source); + } + /** * @param $source * @return array|bool|float|int|mixed|string|null @@ -176,17 +188,15 @@ protected function canParseAndProcess() protected function parseData($source = null) { $ext = $this->getExtension($source); - if ($this->isSourceRemote($source)) { - $source = $this->getRemoteData($source); - } + $sourceData = $this->getData($source); if ($ext === self::SOURCE_YAML) { - return $this->parseYamlData($source); + return $this->parseYamlData($sourceData); } if ($ext === self::SOURCE_CSV) { - return $this->parseCsvData($source); + return $this->parseCsvData($sourceData); } if ($ext === self::SOURCE_JSON) { - return $this->parseJsonData($source); + return $this->parseJsonData($sourceData); } } @@ -217,10 +227,7 @@ private function getExtension($source) */ private function parseYamlData($source) { - $path = BP . '/' . $source; - // phpcs:ignore Magento2.Functions.DiscouragedFunction - $data = file_get_contents($path); - return (new Yaml())->parse($data); + return (new Yaml())->parse($source); } /** From 6b059364d2cbcbf53076345d759869745bb36eaf Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 29 Nov 2019 12:02:04 +0000 Subject: [PATCH 05/51] If a default group hasn't been provided then use a default value --- Component/Categories.php | 45 ++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/Component/Categories.php b/Component/Categories.php index ba7bafa..cebe4cc 100644 --- a/Component/Categories.php +++ b/Component/Categories.php @@ -41,22 +41,19 @@ public function processData($data = null) if (isset($data['categories'])) { foreach ($data['categories'] as $store) { try { - if (isset($store['store_group'])) { - // Get the default category - $category = $this->getDefaultCategory($store['store_group']); - if ($category === false) { - throw new ComponentException( - sprintf('No default category was found for the store group "%s"', $store['store_group']) - ); - } - - if (isset($store['categories'])) { - $this->log->logInfo( - sprintf('Updating categories for "%s"', $store['store_group']) - ); - $this->createOrUpdateCategory($category, $store['categories']); - } + $group = $this->getStoreGroup($store); + // Get the default category + $category = $this->getDefaultCategory($group); + if ($category === false) { + throw new ComponentException( + sprintf('No default category was found for the store group "%s"', $group) + ); } + if (isset($store['categories'])) { + $this->log->logInfo(sprintf('Updating categories for "%s"', $group)); + $this->createOrUpdateCategory($category, $store['categories']); + } + } catch (ComponentException $e) { $this->log->logError($e->getMessage()); } @@ -129,11 +126,11 @@ public function createOrUpdateCategory( $path = parse_url($value); $catMediaDir = $this->dirList->getPath('media') . '/' . 'catalog' . '/' . 'category' . '/'; - if (! array_key_exists('host', $path)) { - $value = BP . '/'. trim($value, '/'); + if (!array_key_exists('host', $path)) { + $value = BP . '/' . trim($value, '/'); } - if (! @copy($value, $catMediaDir . $img)) { + if (!@copy($value, $catMediaDir . $img)) { $this->log->logError('Failed to find image: ' . $value, 1); break; } @@ -170,4 +167,16 @@ public function createOrUpdateCategory( } } } + + /** + * @param $data + * @return string + */ + private function getStoreGroup($data) + { + if (isset($data['store_group']) === true) { + return $data['store_group']; + } + return 'Main Website Store'; + } } From e1a0c34f409c2c03ecfd5d2ce4c3a5dba05ecde2 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 29 Nov 2019 13:08:00 +0000 Subject: [PATCH 06/51] Define missing property. --- Component/Categories.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Component/Categories.php b/Component/Categories.php index cebe4cc..2c3ce3e 100644 --- a/Component/Categories.php +++ b/Component/Categories.php @@ -13,6 +13,7 @@ class Categories extends ComponentAbstract protected $name = 'Categories'; protected $description = 'Component to import categories.'; protected $groupFactory; + protected $dirList; protected $category; private $mainAttributes = [ 'name', From cc27521460eab18af46f54ade2bf0f70f569933e Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 29 Nov 2019 13:40:13 +0000 Subject: [PATCH 07/51] Remove empty line. --- Component/Categories.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Component/Categories.php b/Component/Categories.php index 2c3ce3e..3db5d76 100644 --- a/Component/Categories.php +++ b/Component/Categories.php @@ -54,7 +54,6 @@ public function processData($data = null) $this->log->logInfo(sprintf('Updating categories for "%s"', $group)); $this->createOrUpdateCategory($category, $store['categories']); } - } catch (ComponentException $e) { $this->log->logError($e->getMessage()); } From ff7ffed5b98a7f9ade4ee25d9b0b6dca1bddefdc Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 29 Nov 2019 15:17:41 +0000 Subject: [PATCH 08/51] Amend error in constructor. --- Component/ProductLinks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Component/ProductLinks.php b/Component/ProductLinks.php index f7bd3fe..61be4e4 100644 --- a/Component/ProductLinks.php +++ b/Component/ProductLinks.php @@ -32,7 +32,7 @@ public function __construct( ProductRepositoryInterface $productRepository, ProductLinkInterfaceFactory $productLinkFactory ) { - parent::__construct($log, $objectManager); + parent::__construct($log, $objectManager, $json); $this->productRepository = $productRepository; $this->productLinkFactory = $productLinkFactory; } From 82ec9efec24f1cff68fd17e048b96c41a1b03753 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Tue, 17 Dec 2019 16:13:20 +0000 Subject: [PATCH 09/51] Update method to get CSV data as it's no longer a file. --- Component/ComponentAbstract.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Component/ComponentAbstract.php b/Component/ComponentAbstract.php index 15547bb..1f32493 100644 --- a/Component/ComponentAbstract.php +++ b/Component/ComponentAbstract.php @@ -237,10 +237,18 @@ private function parseYamlData($source) */ private function parseCsvData($source) { - $file = new File(); - $parser = new Csv($file); - - return $parser->getData($source); + $lines = explode("\n", $source); + $headerRow = str_getcsv(array_shift($lines)); + $csvData = [$headerRow]; + foreach ($lines as $line) { + $csvLine = str_getcsv($line); + $csvRow = []; + foreach ($headerRow as $key => $column) { + $csvRow[$key] = (array_key_exists($key, $csvLine) === true) ? $csvLine[$key] : ''; + } + $csvData[] = $csvRow; + } + return $csvData; } /** From b1ee1eedecd2d25e9eadca5bbe1a46d82d825e4b Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 20 Dec 2019 16:23:04 +0000 Subject: [PATCH 10/51] Allow for the ability to set the component file type using master.yaml. --- Component/ComponentAbstract.php | 26 +++++++++++++++++++++++++- Model/Processor.php | 5 ++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Component/ComponentAbstract.php b/Component/ComponentAbstract.php index 1f32493..544c39a 100644 --- a/Component/ComponentAbstract.php +++ b/Component/ComponentAbstract.php @@ -27,6 +27,11 @@ abstract class ComponentAbstract protected $objectManager; protected $description = 'Unknown Component'; + /** + * @var string + */ + private $sourceFileType; + /** * @var Json */ @@ -187,7 +192,7 @@ protected function canParseAndProcess() */ protected function parseData($source = null) { - $ext = $this->getExtension($source); + $ext = ($this->getSourceFileType() !== null) ? $this->getSourceFileType() : $this->getExtension($source); $sourceData = $this->getData($source); if ($ext === self::SOURCE_YAML) { return $this->parseYamlData($sourceData); @@ -260,6 +265,25 @@ private function parseJsonData($source) return $jsonData = $this->json->unserialize($source); } + /** + * @param $type + */ + public function setSourceFileType($type) + { + if ($type !== self::SOURCE_JSON && $type !== self::SOURCE_CSV && $type !== self::SOURCE_YAML) { + throw new ComponentException(sprintf('The source file type %s is not valid.', $type)); + } + $this->sourceFileType = $type; + } + + /** + * @return string + */ + public function getSourceFileType() + { + return $this->sourceFileType; + } + /** * This method should be used to process the data and populate the Magento Database. * diff --git a/Model/Processor.php b/Model/Processor.php index 96a690e..cc61c09 100644 --- a/Model/Processor.php +++ b/Model/Processor.php @@ -178,6 +178,9 @@ public function runComponent($componentAlias, $componentConfig) /* @var ComponentAbstract $component */ $component = $this->componentFactory->create($componentClass); + if (isset($componentConfig['type']) === true) { + $component->setSourceFileType($componentConfig['type']); + } if (isset($componentConfig['sources'])) { foreach ($componentConfig['sources'] as $source) { $component->setSource($source)->process(); @@ -218,7 +221,7 @@ public function runComponent($componentAlias, $componentConfig) ); return; } - + // If there are sources for the environment, process them foreach ((array) $componentConfig['env'][$this->getEnvironment()]['sources'] as $source) { $component->setSource($source)->process(); From cca47d1f70bbd230046e77cea33267b06112f35a Mon Sep 17 00:00:00 2001 From: Raj Chevli Date: Fri, 3 Jan 2020 15:54:23 +0000 Subject: [PATCH 11/51] Quick code sniffer fixes --- Component/Attributes.php | 4 ++-- Component/Processor/SqlSplitProcessor.php | 20 ++++++++------------ 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/Component/Attributes.php b/Component/Attributes.php index 809ea1f..7326998 100644 --- a/Component/Attributes.php +++ b/Component/Attributes.php @@ -76,12 +76,12 @@ class Attributes extends YamlComponentAbstract protected $entityTypeId = Product::ENTITY; /** - * @var bool + * @var bool */ protected $updateAttribute = true; /** - * @var bool + * @var bool */ protected $attributeExists = false; diff --git a/Component/Processor/SqlSplitProcessor.php b/Component/Processor/SqlSplitProcessor.php index b536b21..d663eff 100644 --- a/Component/Processor/SqlSplitProcessor.php +++ b/Component/Processor/SqlSplitProcessor.php @@ -45,7 +45,7 @@ public function __construct( /** * @param string $name - * @param string $fileContent + * @param string $filePath * * return void */ @@ -85,7 +85,8 @@ public function process($name, $filePath) * Split file content string into separate queries, allowing for * multi-line queries using preg_match * - * @param string $fileContent + * @param string $filePath + * @param string $delimiter * * @return array */ @@ -93,28 +94,23 @@ private function extractQueriesFromFile($filePath, $delimiter = ';') { $queries = []; $file = fopen($filePath, 'r'); - if (is_resource($file) === true) - { + if (is_resource($file) === true) { $query = []; - while (feof($file) === false) - { + while (feof($file) === false) { $query[] = fgets($file); - if (preg_match('~' . preg_quote($delimiter, '~') . '\s*$~iS', end($query)) === 1) - { + if (preg_match('~' . preg_quote($delimiter, '~') . '\s*$~iS', end($query)) === 1) { $query = trim(implode('', $query)); $queries[] = $query; - while (ob_get_level() > 0) - { + while (ob_get_level() > 0) { ob_end_flush(); } flush(); } - if (is_string($query) === true) - { + if (is_string($query) === true) { $query = []; } } From d9a467b394e6240c7667b22ae7b5a52ea9db234a Mon Sep 17 00:00:00 2001 From: Raj Chevli Date: Fri, 3 Jan 2020 15:54:42 +0000 Subject: [PATCH 12/51] Bring travis testing in line with latest versions of Magento --- .travis.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 110d6d2..6f509a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,8 @@ dist: trusty language: php php: - - 7.0 - - 7.1 + - 7.2 + - 7.3 services: - mysql sudo: required @@ -11,25 +11,25 @@ env: - TEST_SUITE=unit - TEST_SUITE=phpcs - TEST_SUITE=configurator - MAGE_VERSION=2.1.15 + MAGE_VERSION=2.2.5 - TEST_SUITE=configurator - MAGE_VERSION=2.2.4 + MAGE_VERSION=2.3.1 - TEST_SUITE=configurator - MAGE_VERSION=2.2.5 + MAGE_VERSION=2.3.2 - TEST_SUITE=configurator - MAGE_VERSION=2.2.6 + MAGE_VERSION=2.3.3 matrix: allow_failures: - - php: 7.0 - - env: TEST_SUITE=configurator MAGE_VERSION=2.1.15 + - php: 7.2 + - env: TEST_SUITE=configurator MAGE_VERSION=2.2.5 before_install: - echo "{\"http-basic\":{\"repo.magento.com\":{\"username\":\"${MAGENTO_USERNAME}\",\"password\":\"${MAGENTO_PASSWORD}\"}}}" > auth.json - - sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then composer require magento/framework:~101.0.0; fi" - - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/framework:~101.0.0; fi" - - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/module-catalog:~102.0.0; fi" - - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/zendframework1:~1.13.0; fi" + - sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then composer require magento/framework:~101.0; fi" + - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/framework:~101.0; fi" + - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/module-catalog:~102.0; fi" + - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/zendframework1:~1.14.0; fi" install: - sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then composer install --prefer-dist; fi" - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer install --prefer-dist; fi" From fba5dfc39762b77afe13da7bc0b50b3027fbddd6 Mon Sep 17 00:00:00 2001 From: Raj Chevli Date: Fri, 3 Jan 2020 15:57:29 +0000 Subject: [PATCH 13/51] Relax magento framework version for travis test --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6f509a5..6ef11bd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,10 +26,10 @@ matrix: before_install: - echo "{\"http-basic\":{\"repo.magento.com\":{\"username\":\"${MAGENTO_USERNAME}\",\"password\":\"${MAGENTO_PASSWORD}\"}}}" > auth.json - - sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then composer require magento/framework:~101.0; fi" - - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/framework:~101.0; fi" - - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/module-catalog:~102.0; fi" - - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/zendframework1:~1.14.0; fi" + - sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then composer require magento/framework; fi" + - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/framework; fi" + - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/module-catalog; fi" + - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/zendframework1; fi" install: - sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then composer install --prefer-dist; fi" - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer install --prefer-dist; fi" From c66ab3eb3900dbc60c9fea3763363d772b466436 Mon Sep 17 00:00:00 2001 From: Raj Chevli Date: Fri, 3 Jan 2020 16:10:57 +0000 Subject: [PATCH 14/51] Further relax versions for travis testing --- .travis.yml | 4 ++-- composer.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6ef11bd..97a1214 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,8 +26,8 @@ matrix: before_install: - echo "{\"http-basic\":{\"repo.magento.com\":{\"username\":\"${MAGENTO_USERNAME}\",\"password\":\"${MAGENTO_PASSWORD}\"}}}" > auth.json - - sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then composer require magento/framework; fi" - - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/framework; fi" + - sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then composer require magento/framework:^102.0.3; fi" + - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/framework:^102.0.3; fi" - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/module-catalog; fi" - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then composer require magento/zendframework1; fi" install: diff --git a/composer.json b/composer.json index 2ac07a2..deb4f4b 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ } ], "require": { - "symfony/yaml": "~3.3|~4.0", + "symfony/yaml": "~3.3|~4.0|~5.0", "firegento/fastsimpleimport": "1.3.1" }, "require-dev": { @@ -19,7 +19,7 @@ "satooshi/php-coveralls": "^1.0", "phpunit/phpunit": "~6.2.0" }, - "version": "2.0.7", + "version": "2.0.8", "autoload": { "files": [ "registration.php" ], "psr-4": { From 6f6f343d732d073031d2044814ef020994ac768c Mon Sep 17 00:00:00 2001 From: Raj Chevli Date: Fri, 3 Jan 2020 16:19:22 +0000 Subject: [PATCH 15/51] Specify a newer version of symfony console for travis testing --- composer.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index deb4f4b..00654ca 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,8 @@ } ], "require": { - "symfony/yaml": "~3.3|~4.0|~5.0", + "symfony/yaml": "~4.0|~5.0", + "symfony/console": "~4.1.0", "firegento/fastsimpleimport": "1.3.1" }, "require-dev": { @@ -19,7 +20,7 @@ "satooshi/php-coveralls": "^1.0", "phpunit/phpunit": "~6.2.0" }, - "version": "2.0.8", + "version": "2.3.0", "autoload": { "files": [ "registration.php" ], "psr-4": { From 2a490211e419e56051e47044d64cb4c1850626f9 Mon Sep 17 00:00:00 2001 From: Raj Chevli Date: Fri, 3 Jan 2020 16:31:07 +0000 Subject: [PATCH 16/51] Update versions and relax versions for dev requirements --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 00654ca..6a3d17f 100644 --- a/composer.json +++ b/composer.json @@ -15,10 +15,10 @@ }, "require-dev": { "phpmd/phpmd": "^2.6", - "squizlabs/php_codesniffer": "3.1.1", - "sebastian/phpcpd": "2.0.4", + "squizlabs/php_codesniffer": "^3.4", + "sebastian/phpcpd": "~3.0 || ~4.0", "satooshi/php-coveralls": "^1.0", - "phpunit/phpunit": "~6.2.0" + "phpunit/phpunit": "^6.2" }, "version": "2.3.0", "autoload": { From 049f0ec978dbb42f7b9a9d7a822abd4499fd8ab6 Mon Sep 17 00:00:00 2001 From: Raj Chevli Date: Fri, 3 Jan 2020 16:41:47 +0000 Subject: [PATCH 17/51] allow 2.3.1 and 2.3.2 to fail as they don't support PHP 7.3 --- .travis.yml | 2 ++ Test/Integration/setup-magento.sh | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 97a1214..ed9bae5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,8 @@ matrix: allow_failures: - php: 7.2 - env: TEST_SUITE=configurator MAGE_VERSION=2.2.5 + - env: TEST_SUITE=configurator MAGE_VERSION=2.3.1 + - env: TEST_SUITE=configurator MAGE_VERSION=2.3.2 before_install: - echo "{\"http-basic\":{\"repo.magento.com\":{\"username\":\"${MAGENTO_USERNAME}\",\"password\":\"${MAGENTO_PASSWORD}\"}}}" > auth.json diff --git a/Test/Integration/setup-magento.sh b/Test/Integration/setup-magento.sh index b18349f..87b589d 100755 --- a/Test/Integration/setup-magento.sh +++ b/Test/Integration/setup-magento.sh @@ -16,10 +16,6 @@ git checkout tags/$1 -b $1 composer install -echo Temporary change versions to attempt to resolve any dependency issue -composer require symfony/config:4.1.* -composer require symfony/dependency-injection:3.3.* - if [ -z "${TRAVIS_TAG}" ]; then echo Require configurator branch: ${TRAVIS_BRANCH} commit: ${TRAVIS_COMMIT} composer require ctidigital/magento2-configurator dev-${TRAVIS_BRANCH}\#${TRAVIS_COMMIT} From 6c609ea26a67dbe779d7ff69351cfd725751d50c Mon Sep 17 00:00:00 2001 From: Raj Chevli Date: Sat, 4 Jan 2020 20:51:00 +0000 Subject: [PATCH 18/51] Some code sniffer fixes --- Component/CatalogPriceRules/CatalogPriceRulesProcessor.php | 6 +++--- Component/Products.php | 2 ++ Component/TieredPrices.php | 1 + Console/Command/ListCommand.php | 6 +++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Component/CatalogPriceRules/CatalogPriceRulesProcessor.php b/Component/CatalogPriceRules/CatalogPriceRulesProcessor.php index 08366ab..7ce1044 100644 --- a/Component/CatalogPriceRules/CatalogPriceRulesProcessor.php +++ b/Component/CatalogPriceRules/CatalogPriceRulesProcessor.php @@ -38,7 +38,7 @@ class CatalogPriceRulesProcessor implements ComponentProcessorInterface /** * @var CatalogRuleRepositoryInterface */ - private $catalogRuleRepository; + private $catalogRuleRepo; /** * @var Job @@ -66,7 +66,7 @@ public function __construct( ) { $this->logger = $logger; $this->ruleFactory = $ruleFactory; - $this->catalogRuleRepository = $catalogRuleRepo; + $this->catalogRuleRepo = $catalogRuleRepo; $this->ruleJob = $ruleJob; } @@ -137,7 +137,7 @@ public function process() try { // Save the rule - $this->catalogRuleRepository->save($rule); + $this->catalogRuleRepo->save($rule); } catch (\Exception $ex) { $this->logger->logError($ex->getMessage()); } diff --git a/Component/Products.php b/Component/Products.php index d024ba5..798a371 100644 --- a/Component/Products.php +++ b/Component/Products.php @@ -179,6 +179,7 @@ protected function processData($data = null) $import->setMultipleValueSeparator(self::SEPARATOR); $import->processImport($productsArray); } catch (\Exception $e) { + $this->log->logError($e->getMessage()); } $this->log->logInfo($import->getLogTrace()); $this->log->logError($import->getErrorMessages()); @@ -385,6 +386,7 @@ private function insertParagraphs($data, $column) */ private function spotHtmlTags($string, $tagname) { + $matches = []; $pattern = "/<$tagname?.*>(.*)<\/$tagname>/"; preg_match($pattern, $string, $matches); return count($matches); diff --git a/Component/TieredPrices.php b/Component/TieredPrices.php index bcbb392..06c11e4 100644 --- a/Component/TieredPrices.php +++ b/Component/TieredPrices.php @@ -119,6 +119,7 @@ protected function processData($data = null) $import->setMultipleValueSeparator(self::SEPARATOR); $import->processImport($pricesArray); } catch (\Exception $e) { + $this->log->logError($e->getMessage()); } $this->log->logInfo($import->getLogTrace()); $this->log->logError($import->getErrorMessages()); diff --git a/Console/Command/ListCommand.php b/Console/Command/ListCommand.php index e4106b7..a1b9bf1 100644 --- a/Console/Command/ListCommand.php +++ b/Console/Command/ListCommand.php @@ -26,7 +26,7 @@ class ListCommand extends Command /** * @var ObjectManagerInterface */ - private $objectManagerInterface; + private $objectManager; public function __construct( ConfiguratorAdapterInterface $configuratorAdapter, @@ -34,7 +34,7 @@ public function __construct( ObjectManagerInterface $objectManager ) { parent::__construct(); - $this->objectManagerInterface = $objectManager; + $this->objectManager = $objectManager; $this->configuratorAdapter = $configuratorAdapter; $this->configInterface = $config; } @@ -57,7 +57,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $count = 1; foreach ($this->configInterface->getAllComponents() as $component) { /* @var \CtiDigital\Configurator\Component\ComponentAbstract $componentClass */ - $componentClass = $this->objectManagerInterface->create($component['class']); + $componentClass = $this->objectManager->create($component['class']); $comment = str_pad($count.') ', 4) . str_pad($componentClass->getComponentAlias(), 20) From 6d4d0b347be01e1ebf624abdd7eff5ac4def5e13 Mon Sep 17 00:00:00 2001 From: Raj Chevli Date: Mon, 6 Jan 2020 12:33:51 +0000 Subject: [PATCH 19/51] Ensure attribute option label is string and not object --- Component/Product/AttributeOption.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Component/Product/AttributeOption.php b/Component/Product/AttributeOption.php index 368e6b5..f18408d 100644 --- a/Component/Product/AttributeOption.php +++ b/Component/Product/AttributeOption.php @@ -146,7 +146,7 @@ public function saveOptions() * @var AttributeOptionInterface $option */ $option = $this->optionFactory->create(); - $option->setLabel($optionLabel); + $option->setLabel($label); $option->setStoreLabels([$optionLabel]); $option->setSortOrder(0); $option->setIsDefault(false); From 45ec4fcc93c022fd8c7e7c88ad044279238087d9 Mon Sep 17 00:00:00 2001 From: Sam Butler-Thompson Date: Thu, 9 Jan 2020 09:29:52 +0000 Subject: [PATCH 20/51] Amend unit test to use file contents and path --- Component/Processor/SqlSplitProcessor.php | 3 ++- Test/Unit/Processor/SqlSplitProcessorTest.php | 5 +++-- Test/Unit/_files/sql/test.sql | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 Test/Unit/_files/sql/test.sql diff --git a/Component/Processor/SqlSplitProcessor.php b/Component/Processor/SqlSplitProcessor.php index d663eff..656d3df 100644 --- a/Component/Processor/SqlSplitProcessor.php +++ b/Component/Processor/SqlSplitProcessor.php @@ -92,6 +92,7 @@ public function process($name, $filePath) */ private function extractQueriesFromFile($filePath, $delimiter = ';') { + $obBaseLevel = ob_get_level(); $queries = []; $file = fopen($filePath, 'r'); if (is_resource($file) === true) { @@ -104,7 +105,7 @@ private function extractQueriesFromFile($filePath, $delimiter = ';') $queries[] = $query; - while (ob_get_level() > 0) { + while (ob_get_level() > $obBaseLevel) { ob_end_flush(); } flush(); diff --git a/Test/Unit/Processor/SqlSplitProcessorTest.php b/Test/Unit/Processor/SqlSplitProcessorTest.php index 7e1261b..02e6a19 100644 --- a/Test/Unit/Processor/SqlSplitProcessorTest.php +++ b/Test/Unit/Processor/SqlSplitProcessorTest.php @@ -21,6 +21,8 @@ */ class SqlSplitProcessorTest extends \PHPUnit\Framework\TestCase { + const TEST_SQL_PATH = '/Unit/_files/sql/test.sql'; + /** * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */ @@ -85,7 +87,6 @@ public function sqlDataProvider() public function testExceptionHandling() { $name = 'name1'; - $fileContent = 'SELECT * FROM unknown'; $exMsg = 'exception message'; $this->mockConnection @@ -102,6 +103,6 @@ public function testExceptionHandling() ->expects($this->once()) ->method('rollBack'); - $this->processor->process($name, $fileContent); + $this->processor->process($name, dirname(dirname(__DIR__)) . self::TEST_SQL_PATH); } } diff --git a/Test/Unit/_files/sql/test.sql b/Test/Unit/_files/sql/test.sql new file mode 100644 index 0000000..abe49a1 --- /dev/null +++ b/Test/Unit/_files/sql/test.sql @@ -0,0 +1 @@ +SELECT * FROM unknown; \ No newline at end of file From 904c64918788f9f30aee8b462a32d0f068afe9c2 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Thu, 9 Jan 2020 11:28:02 +0000 Subject: [PATCH 21/51] Allow images to be added using the additional_images column. Fix unit test constructor arguments. --- Component/Product/Image.php | 62 ++++++++++++++----- Component/Products.php | 5 +- Test/Unit/Component/AdminRolesTest.php | 1 + Test/Unit/Component/AdminUsersTest.php | 1 + Test/Unit/Component/ApiIntegrationsTest.php | 1 + Test/Unit/Component/AttributeSetsTest.php | 1 + Test/Unit/Component/AttributesTest.php | 2 +- Test/Unit/Component/BlocksTest.php | 2 +- Test/Unit/Component/CatalogPriceRulesTest.php | 1 + .../Component/ComponentAbstractTestCase.php | 7 +++ Test/Unit/Component/ConfigTest.php | 1 + Test/Unit/Component/CustomerGroupsTest.php | 1 + Test/Unit/Component/MediaTest.php | 2 +- Test/Unit/Component/PagesTest.php | 1 + Test/Unit/Component/ProductLinksTest.php | 1 + Test/Unit/Component/ReviewRatingTest.php | 1 + Test/Unit/Component/RewritesTest.php | 1 + Test/Unit/Component/SqlTest.php | 1 + Test/Unit/Component/TaxRatesTest.php | 1 + Test/Unit/Component/TaxRulesTest.php | 1 + Test/Unit/Component/WebsitesTest.php | 1 + Test/Unit/Component/WidgetsTest.php | 1 + 22 files changed, 78 insertions(+), 18 deletions(-) diff --git a/Component/Product/Image.php b/Component/Product/Image.php index fc3f7d3..027bf5b 100644 --- a/Component/Product/Image.php +++ b/Component/Product/Image.php @@ -27,6 +27,11 @@ class Image */ protected $importerConfig; + /** + * @var string + */ + private $separator = ';'; + /** * Image constructor. * @@ -47,6 +52,22 @@ public function __construct( $this->httpClientFactory = $httpClientFactory; } + /** + * @param $separator + */ + public function setSeparator($separator) + { + $this->separator = $separator; + } + + /** + * @return string + */ + public function getSeparator() + { + return $this->separator; + } + /** * Checks if a value is a URL * @@ -91,7 +112,12 @@ public function downloadFile($value) */ public function getFileName($url) { - return basename($url); + $imageName = basename($url); + // Remove any URL entities + $imageName = urldecode($imageName); + // Replace spaces with - + $imageName = preg_replace('/\s+/', '-', $imageName); + return $imageName; } /** @@ -144,20 +170,28 @@ private function isValidImage($file) */ public function getImage($value) { - if ($this->isValueURL($value) === false) { - return $value; - } - if ($this->localFileExists($value)) { - return $this->getFileName($value); - } - $this->log->logInfo(sprintf('Downloading image %s', $value)); - $file = $this->downloadFile($value); - if (strlen($file) > 0) { - $fileName = $this->getFileName($value); - $fileContent = $this->saveFile($fileName, $file); - return $fileContent; + $validImages = []; + $images = explode(',', $value); + foreach ($images as $image) { + if ($this->isValueURL($image) === false) { + $validImages[] = $image; + continue; + } + if ($this->localFileExists($image)) { + $validImages[] = $this->getFileName($image); + continue; + } + $this->log->logInfo(sprintf('Downloading image %s', $image)); + $file = $this->downloadFile($image); + if (strlen($file) > 0) { + $fileName = $this->getFileName($image); + $fileContent = $this->saveFile($fileName, $file); + if ($fileContent !== '') { + $validImages[] = $fileContent; + } + } } - return $value; + return implode($this->getSeparator(), $validImages); } /** diff --git a/Component/Products.php b/Component/Products.php index 57e3389..66af210 100644 --- a/Component/Products.php +++ b/Component/Products.php @@ -31,7 +31,8 @@ class Products extends ComponentAbstract 'image', 'small_image', 'thumbnail', - 'media_image' + 'media_image', + 'additional_images' ]; /** @@ -131,6 +132,7 @@ protected function processData($data = null) ); } $attributeKeys = $this->getAttributesFromCsv($data); + $this->image->setSeparator(self::SEPARATOR); $this->skuColumn = $this->getSkuColumnIndex($attributeKeys); $totalColumnCount = count($attributeKeys); unset($data[0]); @@ -181,6 +183,7 @@ protected function processData($data = null) $import->setMultipleValueSeparator(self::SEPARATOR); $import->processImport($productsArray); } catch (\Exception $e) { + $this->log->logError($e->getMessage()); } $this->log->logInfo($import->getLogTrace()); $this->log->logError($import->getErrorMessages()); diff --git a/Test/Unit/Component/AdminRolesTest.php b/Test/Unit/Component/AdminRolesTest.php index 9c49cc5..5c13f6d 100644 --- a/Test/Unit/Component/AdminRolesTest.php +++ b/Test/Unit/Component/AdminRolesTest.php @@ -21,6 +21,7 @@ protected function componentSetUp() $this->component = new AdminRoles( $this->logInterface, $this->objectManager, + $this->json, $roleFactory, $rulesFactory ); diff --git a/Test/Unit/Component/AdminUsersTest.php b/Test/Unit/Component/AdminUsersTest.php index 64dcbd1..bc4e7b3 100644 --- a/Test/Unit/Component/AdminUsersTest.php +++ b/Test/Unit/Component/AdminUsersTest.php @@ -21,6 +21,7 @@ protected function componentSetUp() $this->component = new AdminUsers( $this->logInterface, $this->objectManager, + $this->json, $userFactory, $rulesFactory ); diff --git a/Test/Unit/Component/ApiIntegrationsTest.php b/Test/Unit/Component/ApiIntegrationsTest.php index 1711c1c..4586fe9 100644 --- a/Test/Unit/Component/ApiIntegrationsTest.php +++ b/Test/Unit/Component/ApiIntegrationsTest.php @@ -34,6 +34,7 @@ protected function componentSetUp() $this->component = new ApiIntegrations( $this->logInterface, $this->objectManager, + $this->json, $integrationFactory, $integrationService, $authorizationService, diff --git a/Test/Unit/Component/AttributeSetsTest.php b/Test/Unit/Component/AttributeSetsTest.php index c37a8ce..2e61a65 100644 --- a/Test/Unit/Component/AttributeSetsTest.php +++ b/Test/Unit/Component/AttributeSetsTest.php @@ -26,6 +26,7 @@ protected function componentSetUp() $this->component = new AttributeSets( $this->logInterface, $this->objectManager, + $this->json, $eavSetup, $attributeSetsRepositoryInterface ); diff --git a/Test/Unit/Component/AttributesTest.php b/Test/Unit/Component/AttributesTest.php index 2caa2f4..ee9d78d 100644 --- a/Test/Unit/Component/AttributesTest.php +++ b/Test/Unit/Component/AttributesTest.php @@ -15,7 +15,7 @@ protected function componentSetUp() ->disableOriginalConstructor() ->getMock(); $attributeRepository = $this->getMockBuilder(AttributeRepositoryInterface::class)->getMock(); - $this->component = new Attributes($this->logInterface, $this->objectManager, $eavSetup, $attributeRepository); + $this->component = new Attributes($this->logInterface, $this->objectManager, $this->json, $eavSetup, $attributeRepository); $this->className = Attributes::class; } } diff --git a/Test/Unit/Component/BlocksTest.php b/Test/Unit/Component/BlocksTest.php index 9f79ede..10909ae 100644 --- a/Test/Unit/Component/BlocksTest.php +++ b/Test/Unit/Component/BlocksTest.php @@ -13,7 +13,7 @@ protected function componentSetUp() $blockInterface = $this->getMockBuilder(BlockInterfaceFactory::class) ->disableOriginalConstructor() ->getMock(); - $this->component = new Blocks($this->logInterface, $this->objectManager, $blockInterface); + $this->component = new Blocks($this->logInterface, $this->objectManager, $this->json, $blockInterface); $this->className = Blocks::class; } } diff --git a/Test/Unit/Component/CatalogPriceRulesTest.php b/Test/Unit/Component/CatalogPriceRulesTest.php index 0e37644..7107364 100644 --- a/Test/Unit/Component/CatalogPriceRulesTest.php +++ b/Test/Unit/Component/CatalogPriceRulesTest.php @@ -33,6 +33,7 @@ protected function componentSetUp() $this->component = new CatalogPriceRules( $this->logInterface, $this->objectManager, + $this->json, $this->mockComponentProcessor ); diff --git a/Test/Unit/Component/ComponentAbstractTestCase.php b/Test/Unit/Component/ComponentAbstractTestCase.php index c0c2c66..61c1c40 100644 --- a/Test/Unit/Component/ComponentAbstractTestCase.php +++ b/Test/Unit/Component/ComponentAbstractTestCase.php @@ -4,6 +4,7 @@ use CtiDigital\Configurator\Component\ComponentAbstract; use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\ObjectManagerInterface; /** @@ -24,6 +25,9 @@ abstract class ComponentAbstractTestCase extends \PHPUnit\Framework\TestCase /* @var $logInterface LoggerInterface */ protected $logInterface; + /* @var $json Json */ + protected $json; + /* @var $testObjectManager \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */ protected $testObjectManager; @@ -41,6 +45,9 @@ protected function setUp() $this->logInterface = $this->getMockBuilder(LoggerInterface::class) ->disableOriginalConstructor() ->getMock(); + $this->json = $this->getMockBuilder(Json::class) + ->disableOriginalConstructor() + ->getMock(); $this->componentSetUp(); } diff --git a/Test/Unit/Component/ConfigTest.php b/Test/Unit/Component/ConfigTest.php index 63462e3..d36c67b 100644 --- a/Test/Unit/Component/ConfigTest.php +++ b/Test/Unit/Component/ConfigTest.php @@ -17,6 +17,7 @@ protected function componentSetUp() $this->component = new Config( $this->logInterface, $this->objectManager, + $this->json, $collectionFactory, $encrypterInterface ); diff --git a/Test/Unit/Component/CustomerGroupsTest.php b/Test/Unit/Component/CustomerGroupsTest.php index c99326c..8fbc0cc 100644 --- a/Test/Unit/Component/CustomerGroupsTest.php +++ b/Test/Unit/Component/CustomerGroupsTest.php @@ -20,6 +20,7 @@ protected function componentSetUp() $this->component = new CustomerGroups( $this->logInterface, $this->objectManager, + $this->json, $groupFactory, $classModelFactory ); diff --git a/Test/Unit/Component/MediaTest.php b/Test/Unit/Component/MediaTest.php index 959ab00..c13b98a 100644 --- a/Test/Unit/Component/MediaTest.php +++ b/Test/Unit/Component/MediaTest.php @@ -12,7 +12,7 @@ protected function componentSetUp() $directoryList = $this->getMockBuilder(\Magento\Framework\App\Filesystem\DirectoryList::class) ->disableOriginalConstructor() ->getMock(); - $this->component = new Media($this->logInterface, $this->objectManager, $directoryList); + $this->component = new Media($this->logInterface, $this->objectManager, $this->json, $directoryList); $this->className = Media::class; } } diff --git a/Test/Unit/Component/PagesTest.php b/Test/Unit/Component/PagesTest.php index 68ee63e..d213f51 100644 --- a/Test/Unit/Component/PagesTest.php +++ b/Test/Unit/Component/PagesTest.php @@ -29,6 +29,7 @@ protected function componentSetUp() new Pages( $this->logInterface, $this->objectManager, + $this->json, $pageRepository, $pageFactory, $storeRepository diff --git a/Test/Unit/Component/ProductLinksTest.php b/Test/Unit/Component/ProductLinksTest.php index 4933d9c..99f9bf3 100644 --- a/Test/Unit/Component/ProductLinksTest.php +++ b/Test/Unit/Component/ProductLinksTest.php @@ -17,6 +17,7 @@ protected function componentSetUp() $this->component = new ProductLinks( $this->logInterface, $this->objectManager, + $this->json, $productRepository, $productLinkFactory ); diff --git a/Test/Unit/Component/ReviewRatingTest.php b/Test/Unit/Component/ReviewRatingTest.php index 40d41c8..1e81307 100644 --- a/Test/Unit/Component/ReviewRatingTest.php +++ b/Test/Unit/Component/ReviewRatingTest.php @@ -19,6 +19,7 @@ protected function componentSetUp() $this->component = new ReviewRating( $this->logInterface, $this->objectManager, + $this->json, $ratingFactory, $storeRepository, $optionFactory, diff --git a/Test/Unit/Component/RewritesTest.php b/Test/Unit/Component/RewritesTest.php index f55d52c..2a512fb 100644 --- a/Test/Unit/Component/RewritesTest.php +++ b/Test/Unit/Component/RewritesTest.php @@ -19,6 +19,7 @@ protected function componentSetUp() $this->component = new Rewrites( $this->logInterface, $this->objectManager, + $this->json, $urlPersistInterface, $urlRewriteFactory ); diff --git a/Test/Unit/Component/SqlTest.php b/Test/Unit/Component/SqlTest.php index 4eceaac..f8ba2b3 100644 --- a/Test/Unit/Component/SqlTest.php +++ b/Test/Unit/Component/SqlTest.php @@ -17,6 +17,7 @@ protected function componentSetUp() $this->component = new Sql( $this->logInterface, $this->objectManager, + $this->json, $mockSqlSplitProc ); diff --git a/Test/Unit/Component/TaxRatesTest.php b/Test/Unit/Component/TaxRatesTest.php index 1e1df1b..d8dddfa 100755 --- a/Test/Unit/Component/TaxRatesTest.php +++ b/Test/Unit/Component/TaxRatesTest.php @@ -15,6 +15,7 @@ protected function componentSetUp() $this->component = new TaxRates( $this->logInterface, $this->objectManager, + $this->json, $csvImportHandler ); diff --git a/Test/Unit/Component/TaxRulesTest.php b/Test/Unit/Component/TaxRulesTest.php index 5106e6b..8b7ed3f 100644 --- a/Test/Unit/Component/TaxRulesTest.php +++ b/Test/Unit/Component/TaxRulesTest.php @@ -23,6 +23,7 @@ protected function componentSetUp() $this->component = new TaxRules( $this->logInterface, $this->objectManager, + $this->json, $rateFactory, $classModelFactory, $ruleFactory diff --git a/Test/Unit/Component/WebsitesTest.php b/Test/Unit/Component/WebsitesTest.php index 2b0158e..a0d36cb 100644 --- a/Test/Unit/Component/WebsitesTest.php +++ b/Test/Unit/Component/WebsitesTest.php @@ -30,6 +30,7 @@ protected function componentSetUp() $this->component = new Websites( $this->logInterface, $this->objectManager, + $this->json, $this->indexerFactory, $this->eventManager, $this->websiteFactory, diff --git a/Test/Unit/Component/WidgetsTest.php b/Test/Unit/Component/WidgetsTest.php index b5ec86a..b663089 100644 --- a/Test/Unit/Component/WidgetsTest.php +++ b/Test/Unit/Component/WidgetsTest.php @@ -24,6 +24,7 @@ protected function componentSetUp() $this->component = new Widgets( $this->logInterface, $this->objectManager, + $this->json, $widgetCollection, $storeFactory, $themeCollection From 282546c541df0dc2a13f5f518aa4665c509ad2df Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Thu, 9 Jan 2020 14:00:19 +0000 Subject: [PATCH 22/51] Code sniffer fixes. --- Component/Processor/SqlSplitProcessor.php | 15 +++++---------- Test/Unit/Component/AttributesTest.php | 8 +++++++- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Component/Processor/SqlSplitProcessor.php b/Component/Processor/SqlSplitProcessor.php index b536b21..1a04921 100644 --- a/Component/Processor/SqlSplitProcessor.php +++ b/Component/Processor/SqlSplitProcessor.php @@ -93,28 +93,23 @@ private function extractQueriesFromFile($filePath, $delimiter = ';') { $queries = []; $file = fopen($filePath, 'r'); - if (is_resource($file) === true) - { + if (is_resource($file) === true) { $query = []; - while (feof($file) === false) - { + while (feof($file) === false) { $query[] = fgets($file); - if (preg_match('~' . preg_quote($delimiter, '~') . '\s*$~iS', end($query)) === 1) - { + if (preg_match('~' . preg_quote($delimiter, '~') . '\s*$~iS', end($query)) === 1) { $query = trim(implode('', $query)); $queries[] = $query; - while (ob_get_level() > 0) - { + while (ob_get_level() > 0) { ob_end_flush(); } flush(); } - if (is_string($query) === true) - { + if (is_string($query) === true) { $query = []; } } diff --git a/Test/Unit/Component/AttributesTest.php b/Test/Unit/Component/AttributesTest.php index ee9d78d..0d97dd0 100644 --- a/Test/Unit/Component/AttributesTest.php +++ b/Test/Unit/Component/AttributesTest.php @@ -15,7 +15,13 @@ protected function componentSetUp() ->disableOriginalConstructor() ->getMock(); $attributeRepository = $this->getMockBuilder(AttributeRepositoryInterface::class)->getMock(); - $this->component = new Attributes($this->logInterface, $this->objectManager, $this->json, $eavSetup, $attributeRepository); + $this->component = new Attributes( + $this->logInterface, + $this->objectManager, + $this->json, + $eavSetup, + $attributeRepository + ); $this->className = Attributes::class; } } From be50d2ff86d628c057d4b1824da0b9c23cffea51 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Thu, 9 Jan 2020 16:17:35 +0000 Subject: [PATCH 23/51] Start refactoring components. --- Api/ComponentInterface.php | 12 ++ Component/AdminRoles.php | 26 +-- Component/AttributeSets.php | 22 +-- Component/Attributes.php | 26 ++- Component/Blocks.php | 25 +-- Component/Categories.php | 55 ++++-- Component/ComponentAbstract.php | 169 +----------------- Component/Config.php | 40 +++-- Component/Media.php | 23 ++- Component/Pages.php | 26 ++- Component/Products.php | 24 +-- Component/Sql.php | 27 ++- Console/Command/ConfiguratorCommand.php | 44 ----- Console/Command/RunCommand.php | 16 -- Model/Processor.php | 160 +++++++++++++++-- .../Command/ConfiguratorCommandTest.php | 57 ------ etc/di.xml | 1 - 17 files changed, 335 insertions(+), 418 deletions(-) create mode 100644 Api/ComponentInterface.php delete mode 100644 Console/Command/ConfiguratorCommand.php delete mode 100644 Test/Unit/Console/Command/ConfiguratorCommandTest.php diff --git a/Api/ComponentInterface.php b/Api/ComponentInterface.php new file mode 100644 index 0000000..b974197 --- /dev/null +++ b/Api/ComponentInterface.php @@ -0,0 +1,12 @@ +roleFactory = $roleFactory; $this->rulesFactory = $rulesFactory; } @@ -53,9 +51,8 @@ public function __construct( /** * @param $data */ - protected function processData($data = null) + protected function execute($data = null) { - if (isset($data['adminroles'])) { foreach ($data['adminroles'] as $role) { try { @@ -69,6 +66,15 @@ protected function processData($data = null) } } + /** + * @param LoggerInterface $logger + */ + public function setLogger(LoggerInterface $logger) + { + $this->log = $logger; + return $this; + } + /** * Create Admin user roles, or update them if they exist * diff --git a/Component/AttributeSets.php b/Component/AttributeSets.php index e072625..92931b2 100644 --- a/Component/AttributeSets.php +++ b/Component/AttributeSets.php @@ -2,14 +2,13 @@ namespace CtiDigital\Configurator\Component; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Exception\ComponentException; -use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Eav\Api\AttributeSetRepositoryInterface; use Magento\Catalog\Model\Product; use Magento\Eav\Api\Data\AttributeSetInterface; use Magento\Eav\Setup\EavSetup; -use Magento\Framework\ObjectManagerInterface; use Magento\Eav\Model\AttributeSetRepository; /** @@ -17,7 +16,7 @@ * @package CtiDigital\Configurator\Model\Component * @SuppressWarnings(PHPMD.LongVariable) */ -class AttributeSets extends ComponentAbstract +class AttributeSets implements ComponentInterface { protected $alias = 'attribute_sets'; protected $name = 'Attribute Sets'; @@ -33,6 +32,11 @@ class AttributeSets extends ComponentAbstract */ protected $attributeSetRepository; + /** + * @var LoggerInterface + */ + private $log; + /** * AttributeSets constructor. * @param LoggerInterface $log @@ -41,23 +45,19 @@ class AttributeSets extends ComponentAbstract * @param AttributeSetRepositoryInterface $attributeSetRepository */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, EavSetup $eavSetup, - AttributeSetRepositoryInterface $attributeSetRepository + AttributeSetRepositoryInterface $attributeSetRepository, + LoggerInterface $log ) { - - parent::__construct($log, $objectManager, $json); - $this->eavSetup = $eavSetup; $this->attributeSetRepository = $attributeSetRepository; + $this->log = $log; } /** * @param array $attributeConfigurationData */ - protected function processData($attributeConfigurationData = null) + public function execute($attributeConfigurationData = null) { try { foreach ($attributeConfigurationData['attribute_sets'] as $attributeSetConfiguration) { diff --git a/Component/Attributes.php b/Component/Attributes.php index 1e16fd9..00dd8a3 100644 --- a/Component/Attributes.php +++ b/Component/Attributes.php @@ -2,21 +2,20 @@ namespace CtiDigital\Configurator\Component; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Exception\ComponentException; -use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Catalog\Model\Product; use Magento\Eav\Api\AttributeRepositoryInterface; use Magento\Eav\Setup\EavSetup; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\ObjectManagerInterface; /** * Class Attributes * @package CtiDigital\Configurator\Model\Component * @SuppressWarnings(PHPMD.LongVariable) */ -class Attributes extends ComponentAbstract +class Attributes implements ComponentInterface { protected $alias = 'attributes'; @@ -38,6 +37,11 @@ class Attributes extends ComponentAbstract */ protected $attributeRepository; + /** + * @var LoggerInterface + */ + private $log; + /** * @var array */ @@ -86,22 +90,26 @@ class Attributes extends ComponentAbstract */ protected $attributeExists = false; + /** + * Attributes constructor. + * @param EavSetup $eavSetup + * @param AttributeRepositoryInterface $attributeRepository + * @param LoggerInterface $log + */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, EavSetup $eavSetup, - AttributeRepositoryInterface $attributeRepository + AttributeRepositoryInterface $attributeRepository, + LoggerInterface $log ) { - parent::__construct($log, $objectManager, $json); $this->eavSetup = $eavSetup; $this->attributeRepository = $attributeRepository; + $this->log = $log; } /** * @param array $attributeConfigurationData */ - protected function processData($attributeConfigurationData = null) + public function execute($attributeConfigurationData = null) { try { foreach ($attributeConfigurationData['attributes'] as $attributeCode => $attributeConfiguration) { diff --git a/Component/Blocks.php b/Component/Blocks.php index 3ce61fe..09a777f 100644 --- a/Component/Blocks.php +++ b/Component/Blocks.php @@ -2,13 +2,13 @@ namespace CtiDigital\Configurator\Component; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Exception\ComponentException; -use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Cms\Api\Data\BlockInterfaceFactory; -use Magento\Framework\ObjectManagerInterface; +use Magento\Store\Model\Store; -class Blocks extends ComponentAbstract +class Blocks implements ComponentInterface { protected $alias = 'blocks'; @@ -30,6 +30,11 @@ class Blocks extends ComponentAbstract */ protected $searchBuilder; + /** + * @var LoggerInterface + */ + private $log; + /** * Blocks constructor. * @param LoggerInterface $log @@ -37,21 +42,19 @@ class Blocks extends ComponentAbstract * @param BlockInterfaceFactory $blockFactory */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, - BlockInterfaceFactory $blockFactory + BlockInterfaceFactory $blockFactory, + Store $store, + LoggerInterface $log ) { - parent::__construct($log, $objectManager, $json); - $this->blockFactory = $blockFactory; - $this->storeManager = $this->objectManager->create(\Magento\Store\Model\Store::class); + $this->storeManager = $store; + $this->log = $log; } /** * @param $data */ - protected function processData($data = null) + public function execute($data = null) { try { foreach ($data as $identifier => $data) { diff --git a/Component/Categories.php b/Component/Categories.php index 3db5d76..7c3777a 100644 --- a/Component/Categories.php +++ b/Component/Categories.php @@ -2,19 +2,39 @@ namespace CtiDigital\Configurator\Component; +use CtiDigital\Configurator\Api\ComponentInterface; +use CtiDigital\Configurator\Api\LoggerInterface; use CtiDigital\Configurator\Exception\ComponentException; -use Magento\Framework\Serialize\Serializer\Json; -use Magento\Framework\Webapi\Exception; -use Symfony\Component\Yaml\Yaml; +use Magento\Catalog\Model\CategoryFactory; +use Magento\Store\Model\GroupFactory; +use Magento\Framework\App\Filesystem\DirectoryList; -class Categories extends ComponentAbstract +class Categories implements ComponentInterface { protected $alias = 'categories'; protected $name = 'Categories'; protected $description = 'Component to import categories.'; - protected $groupFactory; - protected $dirList; - protected $category; + + /** + * @var GroupFactory + */ + private $groupFactory; + + /** + * @var DirectoryList + */ + private $dirList; + + /** + * @var CategoryFactory + */ + private $category; + + /** + * @var LoggerInterface + */ + private $log; + private $mainAttributes = [ 'name', 'is_active', @@ -23,21 +43,26 @@ class Categories extends ComponentAbstract 'description' ]; + /** + * Categories constructor. + * @param CategoryFactory $category + * @param GroupFactory $groupFactory + * @param DirectoryList $dirList + * @param LoggerInterface $log + */ public function __construct( - \CtiDigital\Configurator\Api\LoggerInterface $log, - \Magento\Framework\ObjectManagerInterface $objectManager, - Json $json, - \Magento\Catalog\Model\CategoryFactory $category, - \Magento\Store\Model\GroupFactory $groupFactory, - \Magento\Framework\App\Filesystem\DirectoryList $dirList + CategoryFactory $category, + GroupFactory $groupFactory, + DirectoryList $dirList, + LoggerInterface $log ) { $this->category = $category; $this->groupFactory = $groupFactory; $this->dirList = $dirList; - parent::__construct($log, $objectManager, $json); + $this->log = $log; } - public function processData($data = null) + public function execute($data = null) { if (isset($data['categories'])) { foreach ($data['categories'] as $store) { diff --git a/Component/ComponentAbstract.php b/Component/ComponentAbstract.php index 544c39a..28f1df3 100644 --- a/Component/ComponentAbstract.php +++ b/Component/ComponentAbstract.php @@ -6,8 +6,6 @@ use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Framework\File\Csv; use Magento\Framework\Filesystem\Driver\File; -use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\Serialize\Serializer\Json; use Symfony\Component\Yaml\Yaml; abstract class ComponentAbstract @@ -15,10 +13,6 @@ abstract class ComponentAbstract const ENABLED = 1; const DISABLED = 0; - const SOURCE_YAML = 'yaml'; - const SOURCE_CSV = 'csv'; - const SOURCE_JSON = 'json'; - protected $log; protected $alias; protected $name; @@ -32,19 +26,10 @@ abstract class ComponentAbstract */ private $sourceFileType; - /** - * @var Json - */ - protected $json; - public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json + LoggerInterface $log ) { $this->log = $log; - $this->objectManager = $objectManager; - $this->json = $json; } /** @@ -101,170 +86,18 @@ public function process() if (!$this->canParseAndProcess()) { return; // @todo show some kind of logging } - - // @todo Include some events to dispatch. -// $this->eventManager->dispatch('configurator_parse_component_before',array('object'=>$this)); -// $this->eventManager->dispatch('configurator_parse_component_before'.$this->alias,array('object'=>$this)); - $this->log->logComment(sprintf("Starting to parse data for %s", $this->getComponentName())); $this->parsedData = $this->parseData($this->source); $this->log->logComment(sprintf("Finished parsing data for %s", $this->getComponentName())); -// $this->eventManager->dispatch( -// 'configurator_process_component_before', -// array('object'=>$this,'source'=>$this->source) -// ); -// $this->eventManager->dispatch('configurator_process_component_before'.$this->alias, -// array('object'=>$this,'source'=>$this->source) -// ); - $this->log->logComment(sprintf("Starting to process data for %s", $this->getComponentName())); $this->processData($this->parsedData); $this->log->logComment(sprintf("Finished processing data for %s", $this->getComponentName())); - -// $this->eventManager->dispatch('configurator_process_component_after',array('object'=>$this)); -// $this->eventManager->dispatch('configurator_process_component_after'.$this->alias,array('object'=>$this)); } catch (ComponentException $e) { $this->log->logError($e->getMessage()); } } - /** - * @return true - */ - public function isSourceRemote($source) - { - return (filter_var($source, FILTER_VALIDATE_URL) !== false) ? true : false; - } - - /** - * @param $source - * @return array|bool|false|float|int|mixed|string|null - * @throws \Exception - */ - private function getData($source) - { - return ($this->isSourceRemote($source) === true) ? - $this->getRemoteData($source) : - file_get_contents(BP . '/' . $source); - } - - /** - * @param $source - * @return array|bool|float|int|mixed|string|null - * @throws \Exception - */ - public function getRemoteData($source) - { - // phpcs:ignore Magento2.Functions.DiscouragedFunction - $streamContext = stream_context_create(['ssl' => ['verify_peer' => false, 'verify_peer_name' => false]]); - // phpcs:ignore Magento2.Functions.DiscouragedFunction - $remoteFile = file_get_contents($source, false, $streamContext); - return $remoteFile; - } - - /** - * This method is used to check whether the data from file or a third party - * can be parsed and processed. (e.g. does a YAML file exist for it?) - * - * This will determine whether the component is enabled or disabled. - * - * @return bool - */ - protected function canParseAndProcess() - { - $path = BP . '/' . $this->source; - // phpcs:ignore Magento2.Functions.DiscouragedFunction - if ($this->isSourceRemote($this->source) === false && !file_exists($path)) { - throw new ComponentException( - sprintf("Could not find file in path %s", $path) - ); - } - return true; - } - - /** - * Whether it be from many files or an external database, parsing (pre-processing) - * the data is done here. - * - * @param $source - * @return mixed - */ - protected function parseData($source = null) - { - $ext = ($this->getSourceFileType() !== null) ? $this->getSourceFileType() : $this->getExtension($source); - $sourceData = $this->getData($source); - if ($ext === self::SOURCE_YAML) { - return $this->parseYamlData($sourceData); - } - if ($ext === self::SOURCE_CSV) { - return $this->parseCsvData($sourceData); - } - if ($ext === self::SOURCE_JSON) { - return $this->parseJsonData($sourceData); - } - } - - /** - * @param $source - * @return string - * @throws \Exception - */ - private function getExtension($source) - { - // phpcs:ignore Magento2.Functions.DiscouragedFunction - $extension = pathinfo($source, PATHINFO_EXTENSION); - if (strtolower($extension) === 'yaml') { - return self::SOURCE_YAML; - } - if (strtolower($extension) === 'csv') { - return self::SOURCE_CSV; - } - if (strtolower($extension) === 'json') { - return self::SOURCE_JSON; - } - throw new ComponentException(sprintf('Source "%s" does not have a valid file extension.', $source)); - } - - /** - * @param $source - * @return mixed - */ - private function parseYamlData($source) - { - return (new Yaml())->parse($source); - } - - /** - * @param $source - * @return array - * @throws \Exception - */ - private function parseCsvData($source) - { - $lines = explode("\n", $source); - $headerRow = str_getcsv(array_shift($lines)); - $csvData = [$headerRow]; - foreach ($lines as $line) { - $csvLine = str_getcsv($line); - $csvRow = []; - foreach ($headerRow as $key => $column) { - $csvRow[$key] = (array_key_exists($key, $csvLine) === true) ? $csvLine[$key] : ''; - } - $csvData[] = $csvRow; - } - return $csvData; - } - - /** - * @param $source - * @return array|bool|float|int|mixed|string|null - */ - private function parseJsonData($source) - { - return $jsonData = $this->json->unserialize($source); - } - /** * @param $type */ diff --git a/Component/Config.php b/Component/Config.php index 28b7026..e244c7d 100644 --- a/Component/Config.php +++ b/Component/Config.php @@ -2,18 +2,18 @@ namespace CtiDigital\Configurator\Component; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Exception\ComponentException; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Framework\Encryption\EncryptorInterface; -use Magento\Framework\ObjectManagerInterface; use Magento\Store\Model\StoreFactory; use Magento\Store\Model\WebsiteFactory; use Magento\Theme\Model\ResourceModel\Theme\Collection; use Magento\Theme\Model\ResourceModel\Theme\CollectionFactory; -use Symfony\Component\Yaml\Yaml; -use Magento\Framework\Serialize\Serializer\Json; +use Magento\Config\Model\ResourceModel\Config as ConfigResource; +use Magento\Framework\App\Config as ScopeConfig; -class Config extends ComponentAbstract +class Config implements ComponentInterface { const PATH_THEME_ID = 'design/theme/theme_id'; @@ -22,12 +22,12 @@ class Config extends ComponentAbstract protected $description = 'Component to set the store/system configuration values'; /** - * @var \Magento\Config\Model\ResourceModel\Config + * @var ConfigResource */ protected $configResource; /** - * @var \Magento\Framework\App\Config + * @var ScopeConfig */ protected $scopeConfig; @@ -41,33 +41,37 @@ class Config extends ComponentAbstract */ protected $encryptor; + /** + * @var LoggerInterface + */ + private $log; + /** * Config constructor. - * - * @param LoggerInterface $log - * @param ObjectManagerInterface $objectManager + * @param ConfigResource $configResource + * @param ScopeConfig $scopeConfig * @param CollectionFactory $collectionFactory + * @param EncryptorInterface $encryptor */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, + ConfigResource $configResource, + ScopeConfig $scopeConfig, CollectionFactory $collectionFactory, - EncryptorInterface $encryptor + EncryptorInterface $encryptor, + LoggerInterface $log ) { - parent::__construct($log, $objectManager, $json); - - $this->configResource = $this->objectManager->create(\Magento\Config\Model\ResourceModel\Config::class); - $this->scopeConfig = $this->objectManager->create(\Magento\Framework\App\Config::class); + $this->configResource = $configResource; + $this->scopeConfig = $scopeConfig; $this->collectionFactory = $collectionFactory; $this->encryptor = $encryptor; + $this->log = $log; } /** * @param $data * @SuppressWarnings(PHPMD) */ - protected function processData($data = null) + public function execute($data = null) { try { $validScopes = array('global', 'websites', 'stores'); diff --git a/Component/Media.php b/Component/Media.php index 3404861..917c340 100644 --- a/Component/Media.php +++ b/Component/Media.php @@ -2,36 +2,43 @@ namespace CtiDigital\Configurator\Component; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Exception\ComponentException; use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\ObjectManagerInterface; -class Media extends ComponentAbstract +class Media implements ComponentInterface { - const FULL_ACCESS = 0777; protected $alias = 'media'; protected $name = 'Media'; protected $description = 'Component to download/maintain media.'; + + /** + * @var DirectoryList + */ protected $directoryList; + /** + * @var LoggerInterface + */ + private $log; + public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, - DirectoryList $directoryList + DirectoryList $directoryList, + LoggerInterface $log ) { - parent::__construct($log, $objectManager, $json); $this->directoryList = $directoryList; + $this->log = $log; } /** * @param $data */ - protected function processData($data = null) + public function execute($data = null) { try { // Load root media path diff --git a/Component/Pages.php b/Component/Pages.php index c72d546..290b3d4 100644 --- a/Component/Pages.php +++ b/Component/Pages.php @@ -2,13 +2,12 @@ namespace CtiDigital\Configurator\Component; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Exception\ComponentException; -use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Cms\Api\Data\PageInterfaceFactory; use Magento\Cms\Api\PageRepositoryInterface; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\ObjectManagerInterface; use Magento\Store\Api\StoreRepositoryInterface; use Magento\Store\Model\StoreManagerInterface; @@ -18,7 +17,7 @@ * * @package CtiDigital\Configurator\Model\Component */ -class Pages extends ComponentAbstract +class Pages implements ComponentInterface { protected $alias = 'pages'; protected $name = 'Pages'; @@ -40,38 +39,37 @@ class Pages extends ComponentAbstract */ private $storeRepository; + /** + * @var LoggerInterface + */ + private $log; + /** * Pages constructor. - * - * @param LoggerInterface $log - * @param ObjectManagerInterface $objectManager * @param PageRepositoryInterface $pageRepository * @param PageInterfaceFactory $pageFactory * @param StoreRepositoryInterface $storeRepository + * @param LoggerInterface $log */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, PageRepositoryInterface $pageRepository, PageInterfaceFactory $pageFactory, - StoreRepositoryInterface $storeRepository + StoreRepositoryInterface $storeRepository, + LoggerInterface $log ) { $this->pageFactory = $pageFactory; $this->pageRepository = $pageRepository; $this->storeRepository = $storeRepository; - - parent::__construct($log, $objectManager, $json); + $this->log = $log; } - /** * Loop through the data array and process page data * * @param $data * @return void */ - protected function processData($data = null) + public function execute($data = null) { try { foreach ($data as $identifier => $data) { diff --git a/Component/Products.php b/Component/Products.php index 66af210..c7bee1b 100644 --- a/Component/Products.php +++ b/Component/Products.php @@ -1,9 +1,8 @@ productFactory= $productFactory; $this->importerFactory = $importerFactory; $this->image = $image; $this->attributeOption = $attributeOption; + $this->log = $log; } /** @@ -123,7 +123,7 @@ public function __construct( * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ - protected function processData($data = null) + public function execute($data = null) { // Get the first row of the CSV file for the attribute columns. if (!isset($data[0])) { diff --git a/Component/Sql.php b/Component/Sql.php index d30990e..5bf7722 100644 --- a/Component/Sql.php +++ b/Component/Sql.php @@ -7,17 +7,16 @@ namespace CtiDigital\Configurator\Component; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Component\Processor\SqlSplitProcessor; use Magento\Framework\App\ResourceConnection; -use Magento\Framework\DB\Adapter\AdapterInterface; -use Magento\Framework\ObjectManagerInterface; /** * Class Sql */ -class Sql extends ComponentAbstract +class Sql implements ComponentInterface { /** * @var string @@ -40,21 +39,21 @@ class Sql extends ComponentAbstract private $processor; /** - * {@inheritdoc} - * + * @var LoggerInterface + */ + private $log; + + /** + * Sql constructor. + * @param SqlSplitProcessor $processor * @param LoggerInterface $log - * @param ResourceConnection $resource - * @param ObjectManagerInterface $objectManager */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, - SqlSplitProcessor $processor + SqlSplitProcessor $processor, + LoggerInterface $log ) { - parent::__construct($log, $objectManager, $json); - $this->processor = $processor; + $this->log = $log; } /** @@ -64,7 +63,7 @@ public function __construct( * * @return void */ - protected function processData($data = null) + public function execute($data = null) { if (!isset($data['sql'])) { return; diff --git a/Console/Command/ConfiguratorCommand.php b/Console/Command/ConfiguratorCommand.php deleted file mode 100644 index 6b3a6c6..0000000 --- a/Console/Command/ConfiguratorCommand.php +++ /dev/null @@ -1,44 +0,0 @@ -configuratorAdapter = $configuratorAdapter; - } - - protected function configure() - { - $this->setName('configurator'); - $this->setDescription('List configurator commands'); - } - - /** - * @param InputInterface $input - * @param OutputInterface $output - * @return void - * @SuppressWarnings(PHPMD) - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - try { - $output->writeln('To do'); - } catch (ConfiguratorAdapterException $e) { - $output->writeln('' . $e->getMessage() . ''); - } - } -} diff --git a/Console/Command/RunCommand.php b/Console/Command/RunCommand.php index 9d02273..18ffb5b 100644 --- a/Console/Command/RunCommand.php +++ b/Console/Command/RunCommand.php @@ -3,8 +3,6 @@ namespace CtiDigital\Configurator\Console\Command; use CtiDigital\Configurator\Exception\ConfiguratorAdapterException; -use CtiDigital\Configurator\Api\ConfigInterface; -use CtiDigital\Configurator\Api\ConfiguratorAdapterInterface; use CtiDigital\Configurator\Model\Processor; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputDefinition; @@ -14,29 +12,15 @@ class RunCommand extends Command { - /** - * @var ConfiguratorAdapterInterface - */ - private $configuratorAdapter; - - /** - * @var ConfigInterface|CtiDigital\Configurator\Console\Command\RunCommand - */ - private $configInterface; - /** * @var Processor */ private $processor; public function __construct( - ConfiguratorAdapterInterface $configuratorAdapter, - ConfigInterface $config, Processor $processor ) { parent::__construct(); - $this->configuratorAdapter = $configuratorAdapter; - $this->configInterface = $config; $this->processor = $processor; } diff --git a/Model/Processor.php b/Model/Processor.php index cc61c09..e95aadf 100644 --- a/Model/Processor.php +++ b/Model/Processor.php @@ -2,6 +2,7 @@ namespace CtiDigital\Configurator\Model; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Api\LoggerInterface; use CtiDigital\Configurator\Component\ComponentAbstract; use CtiDigital\Configurator\Exception\ComponentException; @@ -10,9 +11,14 @@ use Symfony\Component\Yaml\Parser; use Magento\Framework\App\State; use Magento\Framework\App\Area; +use Symfony\Component\Yaml\Yaml; class Processor { + const SOURCE_YAML = 'yaml'; + const SOURCE_CSV = 'csv'; + const SOURCE_JSON = 'json'; + /** * @var string */ @@ -176,14 +182,15 @@ public function runComponent($componentAlias, $componentConfig) $componentClass = $this->configInterface->getComponentByName($componentAlias); - /* @var ComponentAbstract $component */ + /* @var ComponentInterface $component */ $component = $this->componentFactory->create($componentClass); - if (isset($componentConfig['type']) === true) { - $component->setSourceFileType($componentConfig['type']); - } + + $sourceType = (isset($componentConfig['type']) === true) ? $componentConfig['type'] : null; + if (isset($componentConfig['sources'])) { foreach ($componentConfig['sources'] as $source) { - $component->setSource($source)->process(); + $sourceData = $this->parseData($source, $sourceType); + $component->execute($sourceData); } } @@ -191,7 +198,7 @@ public function runComponent($componentAlias, $componentConfig) if (!isset($componentConfig['env'])) { // If not, continue to next component $this->log->logComment( - sprintf("No environment node for '%s' component", $component->getComponentName()) + sprintf("No environment node for '%s' component", $componentAlias) ); return; } @@ -203,7 +210,7 @@ public function runComponent($componentAlias, $componentConfig) sprintf( "No '%s' environment specific node for '%s' component", $this->getEnvironment(), - $component->getComponentName() + $componentAlias ) ); return; @@ -216,7 +223,7 @@ public function runComponent($componentAlias, $componentConfig) sprintf( "No '%s' environment specific sources for '%s' component", $this->getEnvironment(), - $component->getComponentName() + $componentAlias ) ); return; @@ -224,7 +231,9 @@ public function runComponent($componentAlias, $componentConfig) // If there are sources for the environment, process them foreach ((array) $componentConfig['env'][$this->getEnvironment()]['sources'] as $source) { - $component->setSource($source)->process(); + $sourceType = (isset($componentConfig['type']) === true) ? $componentConfig['type'] : null; + $sourceData = $this->parseData($source, $sourceType); + $component->execute($sourceData); } } @@ -269,7 +278,7 @@ private function isValidComponent($componentName) $this->log->logComment(sprintf("The %s component has %s class name.", $componentName, $componentClass)); $component = $this->componentFactory->create($componentClass); - if ($component instanceof ComponentAbstract) { + if ($component instanceof ComponentInterface) { return true; } return false; @@ -330,4 +339,135 @@ private function validateMasterYaml($master) $this->log->logError($e->getMessage()); } } + + private function parseData($source, $sourceType) + { + if ($this->canParseAndProcess($source) === true) { + $ext = ($sourceType !== null) ? $sourceType : $this->getExtension($source); + $sourceData = $this->getData($source); + if ($ext === self::SOURCE_YAML) { + return $this->parseYamlData($sourceData); + } + if ($ext === self::SOURCE_CSV) { + return $this->parseCsvData($sourceData); + } + if ($ext === self::SOURCE_JSON) { + return $this->parseJsonData($sourceData); + } + } + } + + /** + * This method is used to check whether the data from file or a third party + * can be parsed and processed. (e.g. does a YAML file exist for it?) + * + * This will determine whether the component is enabled or disabled. + * + * @return bool + */ + private function canParseAndProcess($source) + { + $path = BP . '/' . $source; + // phpcs:ignore Magento2.Functions.DiscouragedFunction + if ($this->isSourceRemote($source) === false && !file_exists($path)) { + throw new ComponentException( + sprintf("Could not find file in path %s", $path) + ); + } + return true; + } + + /** + * @return true + */ + public function isSourceRemote($source) + { + return (filter_var($source, FILTER_VALIDATE_URL) !== false) ? true : false; + } + + /** + * @param $source + * @return string + * @throws \Exception + */ + private function getExtension($source) + { + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $extension = pathinfo($source, PATHINFO_EXTENSION); + if (strtolower($extension) === 'yaml') { + return self::SOURCE_YAML; + } + if (strtolower($extension) === 'csv') { + return self::SOURCE_CSV; + } + if (strtolower($extension) === 'json') { + return self::SOURCE_JSON; + } + throw new ComponentException(sprintf('Source "%s" does not have a valid file extension.', $source)); + } + + /** + * @param $source + * @return array|bool|false|float|int|mixed|string|null + * @throws \Exception + */ + private function getData($source) + { + return ($this->isSourceRemote($source) === true) ? + $this->getRemoteData($source) : + file_get_contents(BP . '/' . $source); + } + + /** + * @param $source + * @return array|bool|float|int|mixed|string|null + * @throws \Exception + */ + public function getRemoteData($source) + { + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $streamContext = stream_context_create(['ssl' => ['verify_peer' => false, 'verify_peer_name' => false]]); + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $remoteFile = file_get_contents($source, false, $streamContext); + return $remoteFile; + } + + /** + * @param $source + * @return mixed + */ + private function parseYamlData($source) + { + return (new Yaml())->parse($source); + } + + /** + * @param $source + * @return array + * @throws \Exception + */ + private function parseCsvData($source) + { + $lines = explode("\n", $source); + $headerRow = str_getcsv(array_shift($lines)); + $csvData = [$headerRow]; + foreach ($lines as $line) { + $csvLine = str_getcsv($line); + $csvRow = []; + foreach ($headerRow as $key => $column) { + $csvRow[$key] = (array_key_exists($key, $csvLine) === true) ? $csvLine[$key] : ''; + } + $csvData[] = $csvRow; + } + return $csvData; + } + + /** + * @param $source + * @return array|bool|float|int|mixed|string|null + */ + private function parseJsonData($source) + { + return $jsonData = json_decode($source); + } } diff --git a/Test/Unit/Console/Command/ConfiguratorCommandTest.php b/Test/Unit/Console/Command/ConfiguratorCommandTest.php deleted file mode 100644 index b219d4c..0000000 --- a/Test/Unit/Console/Command/ConfiguratorCommandTest.php +++ /dev/null @@ -1,57 +0,0 @@ -configuratorCommandAdapter = $this->getMockBuilder(ConfiguratorAdapterInterface::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->command = new ConfiguratorCommand($this->configuratorCommandAdapter); - $this->mockInput = $this->getMockBuilder(InputInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->mockOutput = $this->getMockBuilder(OutputInterface::class) - ->disableOriginalConstructor() - ->getMock(); - } - - public function testItIsAConsoleCommand() - { - $this->assertInstanceOf(Command::class, $this->command); - } - - public function testItHasTheCorrectName() - { - $this->assertSame('configurator', $this->command->getName()); - } -} diff --git a/etc/di.xml b/etc/di.xml index 167e52f..fbb32a2 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -11,7 +11,6 @@ - CtiDigital\Configurator\Console\Command\ConfiguratorCommand CtiDigital\Configurator\Console\Command\ListCommand CtiDigital\Configurator\Console\Command\RunCommand From 076153b6041d34cbafd75b3a78579253fee9b959 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Thu, 9 Jan 2020 16:26:13 +0000 Subject: [PATCH 24/51] Refactor components. --- Component/AdminUsers.php | 25 +++--- Component/ApiIntegrations.php | 22 +++--- Component/CatalogPriceRules.php | 19 +++-- Component/ComponentAbstract.php | 127 ------------------------------- Component/CustomerAttributes.php | 26 +++++-- Component/CustomerGroups.php | 21 +++-- 6 files changed, 64 insertions(+), 176 deletions(-) delete mode 100644 Component/ComponentAbstract.php diff --git a/Component/AdminUsers.php b/Component/AdminUsers.php index ccac743..40c3a74 100644 --- a/Component/AdminUsers.php +++ b/Component/AdminUsers.php @@ -1,15 +1,13 @@ userFactory = $userFactory; $this->roleFactory = $roleFactory; + $this->log = $log; } /** * @param data */ - protected function processData($data = null) + public function execute($data = null) { //Get Each Role foreach ($data['adminusers'] as $roleSet) { diff --git a/Component/ApiIntegrations.php b/Component/ApiIntegrations.php index 8ebb0f4..7a33a83 100644 --- a/Component/ApiIntegrations.php +++ b/Component/ApiIntegrations.php @@ -1,6 +1,7 @@ integrationFactory = $integrationFactory; $this->integrationService = $integrationService; $this->authorizationService = $authorizationService; $this->tokenFactory = $tokenFactory; + $this->log = $log; } /** * @param array $data */ - protected function processData($data = null) + public function execute($data = null) { if (isset($data['apiintegrations'])) { foreach ($data['apiintegrations'] as $integrationData) { diff --git a/Component/CatalogPriceRules.php b/Component/CatalogPriceRules.php index d2c44b9..a3350f3 100644 --- a/Component/CatalogPriceRules.php +++ b/Component/CatalogPriceRules.php @@ -7,6 +7,7 @@ namespace CtiDigital\Configurator\Component; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Api\ComponentProcessorInterface; use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; @@ -16,7 +17,7 @@ /** * Class CatalogPriceRules */ -class CatalogPriceRules extends ComponentAbstract +class CatalogPriceRules implements ComponentInterface { /** * @var string @@ -38,6 +39,11 @@ class CatalogPriceRules extends ComponentAbstract */ private $processor; + /** + * @var LoggerInterface + */ + private $log; + /** * CatalogPriceRules constructor. * @@ -46,14 +52,11 @@ class CatalogPriceRules extends ComponentAbstract * @param ComponentProcessorInterface $processor */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, - ComponentProcessorInterface $processor + ComponentProcessorInterface $processor, + LoggerInterface $log ) { - parent::__construct($log, $objectManager, $json); - $this->processor = $processor; + $this->log = $log; } /** @@ -63,7 +66,7 @@ public function __construct( * * @return void */ - protected function processData($data = null) + public function execute($data = null) { $rules = $data['rules'] ?: []; $config = $data['config'] ?: []; diff --git a/Component/ComponentAbstract.php b/Component/ComponentAbstract.php deleted file mode 100644 index 28f1df3..0000000 --- a/Component/ComponentAbstract.php +++ /dev/null @@ -1,127 +0,0 @@ -log = $log; - } - - /** - * Obtain the source of the data. - * Most likely to be a file path from the master.yaml - * - * @param $source - * @return ComponentAbstract - */ - public function setSource($source) - { - $this->source = $source; - return $this; - } - - /** - * This is a human friendly component name for logging purposes. - * - * @return string - */ - public function getComponentName() - { - return $this->name; - } - - /** - * This is to provide a system friendly alias that can be used on the command line - * so a component can be ran on its own as well as for logging purposes. - * - * @return string - */ - public function getComponentAlias() - { - return $this->alias; - } - - /** - * Gets a small description of the component used for when listing the component - * - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * The function that runs the component (and every other component) - */ - public function process() - { - try { - // Check if a component can be parsed and processed - if (!$this->canParseAndProcess()) { - return; // @todo show some kind of logging - } - $this->log->logComment(sprintf("Starting to parse data for %s", $this->getComponentName())); - $this->parsedData = $this->parseData($this->source); - $this->log->logComment(sprintf("Finished parsing data for %s", $this->getComponentName())); - - $this->log->logComment(sprintf("Starting to process data for %s", $this->getComponentName())); - $this->processData($this->parsedData); - $this->log->logComment(sprintf("Finished processing data for %s", $this->getComponentName())); - } catch (ComponentException $e) { - $this->log->logError($e->getMessage()); - } - } - - /** - * @param $type - */ - public function setSourceFileType($type) - { - if ($type !== self::SOURCE_JSON && $type !== self::SOURCE_CSV && $type !== self::SOURCE_YAML) { - throw new ComponentException(sprintf('The source file type %s is not valid.', $type)); - } - $this->sourceFileType = $type; - } - - /** - * @return string - */ - public function getSourceFileType() - { - return $this->sourceFileType; - } - - /** - * This method should be used to process the data and populate the Magento Database. - * - * @param $data - * @return void - */ - abstract protected function processData($data = null); -} diff --git a/Component/CustomerAttributes.php b/Component/CustomerAttributes.php index b05afc0..3636bb2 100644 --- a/Component/CustomerAttributes.php +++ b/Component/CustomerAttributes.php @@ -2,6 +2,7 @@ namespace CtiDigital\Configurator\Component; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Exception\ComponentException; @@ -19,7 +20,7 @@ * @package CtiDigital\Configurator\Model\Component * @SuppressWarnings(PHPMD.LongVariable) */ -class CustomerAttributes extends Attributes +class CustomerAttributes implements ComponentInterface { const DEFAULT_ATTRIBUTE_SET_ID = 1; const DEFAULT_ATTRIBUTE_GROUP_ID = 1; @@ -49,6 +50,11 @@ class CustomerAttributes extends Attributes */ protected $attributeResource; + /** + * @var LoggerInterface + */ + private $log; + /** * @var array */ @@ -61,25 +67,31 @@ class CustomerAttributes extends Attributes ] ]; + /** + * CustomerAttributes constructor. + * @param EavSetup $eavSetup + * @param AttributeRepository $attributeRepository + * @param CustomerSetupFactory $customerSetupFactory + * @param Attribute $attributeResource + * @param LoggerInterface $log + */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, EavSetup $eavSetup, AttributeRepository $attributeRepository, CustomerSetupFactory $customerSetupFactory, - Attribute $attributeResource + Attribute $attributeResource, + LoggerInterface $log ) { $this->attributeConfigMap = array_merge($this->attributeConfigMap, $this->customerConfigMap); $this->customerSetup = $customerSetupFactory; $this->attributeResource = $attributeResource; - parent::__construct($log, $objectManager, $json, $eavSetup, $attributeRepository); + $this->log = $log; } /** * @param array $attributeConfigurationData */ - protected function processData($attributeConfigurationData = null) + public function execute($attributeConfigurationData = null) { try { foreach ($attributeConfigurationData['customer_attributes'] as $attributeCode => $attributeConfiguration) { diff --git a/Component/CustomerGroups.php b/Component/CustomerGroups.php index a54fd7f..431ffd1 100644 --- a/Component/CustomerGroups.php +++ b/Component/CustomerGroups.php @@ -1,15 +1,13 @@ groupFactory = $groupFactory; $this->classModelFactory = $classModelFactory; + $this->log = $log; } /** * @param $data */ - protected function processData($data = null) + public function execute($data = null) { foreach ($data['customergroups'] as $taxClass) { $taxClassName = $taxClass['taxclass']; From c8796bc54dccc7cccc5609b09d9295e52d7c44d0 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 08:30:25 +0000 Subject: [PATCH 25/51] Refactor components. --- Component/AdminRoles.php | 4 +- Component/Customers.php | 31 ++++++++------- Component/Media.php | 2 - Component/ProductLinks.php | 37 +++++++++++------ Component/Products.php | 9 +++-- Component/ReviewRating.php | 28 ++++++++----- Component/Rewrites.php | 29 +++++++------- Component/ShippingTableRates.php | 30 +++++++------- Component/Sql.php | 3 +- Component/TaxRates.php | 30 +++++++------- Component/TaxRules.php | 25 ++++++------ Component/TieredPrices.php | 31 ++++++++------- Component/Websites.php | 40 ++++++++++--------- Component/Widgets.php | 68 +++++++++++++++++++++++--------- 14 files changed, 212 insertions(+), 155 deletions(-) diff --git a/Component/AdminRoles.php b/Component/AdminRoles.php index 32e44f0..8e22e69 100644 --- a/Component/AdminRoles.php +++ b/Component/AdminRoles.php @@ -3,8 +3,6 @@ use CtiDigital\Configurator\Api\ComponentInterface; use Magento\Authorization\Model\RoleFactory; -use Magento\Framework\Serialize\Serializer\Json; -use Magento\Framework\ObjectManagerInterface; use Magento\Authorization\Model\RulesFactory; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Authorization\Model\UserContextInterface; @@ -51,7 +49,7 @@ public function __construct( /** * @param $data */ - protected function execute($data = null) + public function execute($data = null) { if (isset($data['adminroles'])) { foreach ($data['adminroles'] as $role) { diff --git a/Component/Customers.php b/Component/Customers.php index c16cd60..27d5fe9 100644 --- a/Component/Customers.php +++ b/Component/Customers.php @@ -1,17 +1,17 @@ importerFactory = $importerFactory; $this->groupRepository = $groupRepository; $this->groupManagement = $groupManagement; $this->criteriaBuilder = $criteriaBuilder; $this->indexerFactory = $indexerFactory; - parent::__construct($log, $objectManager, $json); + $this->log = $log; } /** @@ -89,7 +92,7 @@ public function __construct( * * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - protected function processData($data = null) + public function execute($data = null) { $this->getColumnHeaders($data); unset($data[0]); diff --git a/Component/Media.php b/Component/Media.php index 917c340..378fca2 100644 --- a/Component/Media.php +++ b/Component/Media.php @@ -4,10 +4,8 @@ use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Exception\ComponentException; -use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Framework\App\Filesystem\DirectoryList; -use Magento\Framework\ObjectManagerInterface; class Media implements ComponentInterface { diff --git a/Component/ProductLinks.php b/Component/ProductLinks.php index 61be4e4..6bca593 100644 --- a/Component/ProductLinks.php +++ b/Component/ProductLinks.php @@ -2,39 +2,50 @@ namespace CtiDigital\Configurator\Component; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Api\LoggerInterface; -use Magento\Framework\Serialize\Serializer\Json; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Api\Data\ProductLinkInterfaceFactory; -use Magento\Framework\ObjectManagerInterface; use CtiDigital\Configurator\Exception\ComponentException; -class ProductLinks extends ComponentAbstract +class ProductLinks implements ComponentInterface { - protected $alias = 'product_links'; protected $name = 'Product Links'; protected $description = 'Component to create and maintain product links (related/up-sells/cross-sells)'; - - // @var Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory + /** + * @var ProductLinkInterfaceFactory + */ protected $productLinkFactory; + /** + * @var ProductRepositoryInterface + */ protected $productRepository; + /** + * @var LoggerInterface + */ + private $log; + protected $allowedLinks = ['relation', 'up_sell', 'cross_sell']; protected $linkTypeMap = ['relation' => 'related', 'up_sell' => 'upsell', 'cross_sell' => 'crosssell']; + /** + * ProductLinks constructor. + * @param ProductRepositoryInterface $productRepository + * @param ProductLinkInterfaceFactory $productLinkFactory + * @param LoggerInterface $log + */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, ProductRepositoryInterface $productRepository, - ProductLinkInterfaceFactory $productLinkFactory + ProductLinkInterfaceFactory $productLinkFactory, + LoggerInterface $log ) { - parent::__construct($log, $objectManager, $json); $this->productRepository = $productRepository; $this->productLinkFactory = $productLinkFactory; + $this->log = $log; } /** @@ -42,7 +53,7 @@ public function __construct( * * @param $data */ - public function processData($data = null) + public function execute($data = null) { try { // Loop through all the product link types - if there are multiple link types in the yaml file @@ -99,7 +110,7 @@ private function processSkus(array $data, $linkType) private function processLinks($sku, $linkSkus, $linkType) { try { - $productLinks = array(); + $productLinks = []; // Loop through all the products that require linking to a product foreach ($linkSkus as $position => $linkSku) { diff --git a/Component/Products.php b/Component/Products.php index c7bee1b..d4ecdf2 100644 --- a/Component/Products.php +++ b/Component/Products.php @@ -138,14 +138,14 @@ public function execute($data = null) unset($data[0]); // Prepare the data - $productsArray = array(); + $productsArray = []; foreach ($data as $product) { if (count($product) !== $totalColumnCount) { $this->skippedProducts[] = $product[$this->skuColumn]; continue; } - $productArray = array(); + $productArray = []; foreach ($attributeKeys as $column => $code) { $product[$column] = $this->clean($product[$column], $code); if (in_array($code, $this->imageAttributes)) { @@ -198,6 +198,7 @@ public function execute($data = null) public function getFileType($source = null) { // Get the file extension so we know how to load the file + // phpcs:ignore Magento2.Functions.DiscouragedFunction $sourceFileInfo = pathinfo($source); if (!isset($sourceFileInfo['extension'])) { throw new ComponentException( @@ -216,7 +217,7 @@ public function getFileType($source = null) */ public function getAttributesFromCsv($data = null) { - $attributes = array(); + $attributes = []; foreach ($data[0] as $attributeCode) { $attributes[] = $attributeCode; } @@ -229,7 +230,7 @@ public function getAttributesFromCsv($data = null) * @param array $data * @return bool */ - public function isConfigurable($data = array()) + public function isConfigurable($data = []) { if (isset($data['product_type']) && $data['product_type'] === 'configurable') { return true; diff --git a/Component/ReviewRating.php b/Component/ReviewRating.php index c52e03a..5352f99 100644 --- a/Component/ReviewRating.php +++ b/Component/ReviewRating.php @@ -1,9 +1,8 @@ ratingFactory = $ratingFactory; $this->storeRepository = $storeRepository; $this->optionFactory = $optionFactory; $this->entityFactory = $entityFactory; - parent::__construct($log, $objectManager, $json); + $this->log = $log; } - public function processData($data = null) + public function execute($data = null) { $reviewRatings = $this->getReviewRatings($data); diff --git a/Component/Rewrites.php b/Component/Rewrites.php index 3bd2302..6b59959 100644 --- a/Component/Rewrites.php +++ b/Component/Rewrites.php @@ -2,14 +2,13 @@ namespace CtiDigital\Configurator\Component; -use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\Serialize\Serializer\Json; -use Magento\UrlRewrite\Model\UrlRewriteFactory; -use Magento\UrlRewrite\Model\UrlPersistInterface; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Exception\ComponentException; use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\UrlRewrite\Model\UrlRewriteFactory; +use Magento\UrlRewrite\Model\UrlPersistInterface; -class Rewrites extends ComponentAbstract +class Rewrites implements ComponentInterface { protected $alias = "rewrites"; protected $name = "rewrites"; @@ -34,29 +33,31 @@ class Rewrites extends ComponentAbstract */ protected $urlRewriteFactory; + /** + * @var LoggerInterface + */ + private $log; + /** * Rewrites constructor. - * @param LoggerInterface $log - * @param ObjectManagerInterface $objectManager * @param UrlPersistInterface $urlPersist * @param UrlRewriteFactory $urlRewriteFactory + * @param LoggerInterface $log */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, UrlPersistInterface $urlPersist, - UrlRewriteFactory $urlRewriteFactory + UrlRewriteFactory $urlRewriteFactory, + LoggerInterface $log ) { - parent::__construct($log, $objectManager, $json); $this->urlPersist = $urlPersist; $this->urlRewriteFactory = $urlRewriteFactory; + $this->log = $log; } /** * @param array|null $data */ - public function processData($data = null) + public function execute($data = null) { $headerRowAttributes = $this->getAttributesFromHeaderRow($data); @@ -99,7 +100,7 @@ public function processData($data = null) public function getAttributesFromHeaderRow($data = null) { $this->checkHeaderRowExists($data); - $attributes = array(); + $attributes = []; foreach ($data[0] as $attributeCode) { $attributes[] = $attributeCode; } diff --git a/Component/ShippingTableRates.php b/Component/ShippingTableRates.php index c2060b2..22cc556 100644 --- a/Component/ShippingTableRates.php +++ b/Component/ShippingTableRates.php @@ -1,11 +1,8 @@ tablerateFactory = $tablerateFactory; $this->websiteFactory = $websiteFactory; $this->regionFactory = $regionFactory; + $this->log = $log; } - /** * This method should be used to process the data and populate the Magento Database. * * @param array $data * @return void */ - public function processData($data = null) + public function execute($data = null) { /** @var Tablerate $tablerateModel */ $tablerateModel = $this->tablerateFactory->create(); @@ -123,7 +121,7 @@ private function createNewShippingTableRate( $regionModel = $this->regionFactory->create(); $regionModel = $regionModel->loadByCode($shippingRate['dest_region_code'], $shippingRate['dest_country_id']); $regionId = $regionModel->getId(); - if (is_null($regionId)) { + if ($regionId === null) { $regionId = 0; } diff --git a/Component/Sql.php b/Component/Sql.php index 5bf7722..e2d91f3 100644 --- a/Component/Sql.php +++ b/Component/Sql.php @@ -9,9 +9,7 @@ use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Api\LoggerInterface; -use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Component\Processor\SqlSplitProcessor; -use Magento\Framework\App\ResourceConnection; /** * Class Sql @@ -72,6 +70,7 @@ public function execute($data = null) $this->log->logInfo('Beginning of custom queries configuration:'); foreach ($data['sql'] as $name => $sqlFile) { $path = BP . '/' . $sqlFile; + // phpcs:ignore Magento2.Functions.DiscouragedFunction if (false === file_exists($path)) { $this->log->logError("{$path} does not exist. Skipping."); continue; diff --git a/Component/TaxRates.php b/Component/TaxRates.php index 18c3d21..a51fad9 100755 --- a/Component/TaxRates.php +++ b/Component/TaxRates.php @@ -2,13 +2,12 @@ namespace CtiDigital\Configurator\Component; -use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\Serialize\Serializer\Json; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Api\LoggerInterface; -use Magento\TaxImportExport\Model\Rate\CsvImportHandler; use CtiDigital\Configurator\Exception\ComponentException; +use Magento\TaxImportExport\Model\Rate\CsvImportHandler; -class TaxRates extends ComponentAbstract +class TaxRates implements ComponentInterface { protected $alias = 'taxrates'; protected $name = 'Tax Rates'; @@ -20,25 +19,28 @@ class TaxRates extends ComponentAbstract protected $csvImportHandler; /** - * TaxRules constructor. - * @param LoggerInterface $log - * @param ObjectManagerInterface $objectManager + * @var LoggerInterface + */ + private $log; + + /** + * TaxRates constructor. * @param CsvImportHandler $csvImportHandler + * @param LoggerInterface $log */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, - CsvImportHandler $csvImportHandler + CsvImportHandler $csvImportHandler, + LoggerInterface $log ) { - parent::__construct($log, $objectManager, $json); $this->csvImportHandler = $csvImportHandler; + $this->log = $log; } /** - * @param array|null $data + * @param null $data + * @throws \Magento\Framework\Exception\LocalizedException */ - protected function processData($data = null) + public function execute($data = null) { //Check Row Data exists if (!isset($data[0])) { diff --git a/Component/TaxRules.php b/Component/TaxRules.php index e796e44..b94e558 100644 --- a/Component/TaxRules.php +++ b/Component/TaxRules.php @@ -2,15 +2,14 @@ namespace CtiDigital\Configurator\Component; -use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\Serialize\Serializer\Json; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Api\LoggerInterface; +use CtiDigital\Configurator\Exception\ComponentException; use Magento\Tax\Model\Calculation\RuleFactory; use Magento\Tax\Model\Calculation\RateFactory; use Magento\Tax\Model\ClassModelFactory; -use CtiDigital\Configurator\Exception\ComponentException; -class TaxRules extends ComponentAbstract +class TaxRules implements ComponentInterface { protected $alias = 'taxrules'; protected $name = 'Tax Rules'; @@ -41,32 +40,34 @@ class TaxRules extends ComponentAbstract */ protected $classModelFactory; + /** + * @var LoggerInterface + */ + private $log; + /** * TaxRules constructor. - * @param LoggerInterface $log - * @param ObjectManagerInterface $objectManager * @param RateFactory $rateFactory * @param ClassModelFactory $classModelFactory * @param RuleFactory $ruleFactory + * @param LoggerInterface $log */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, RateFactory $rateFactory, ClassModelFactory $classModelFactory, - RuleFactory $ruleFactory + RuleFactory $ruleFactory, + LoggerInterface $log ) { - parent::__construct($log, $objectManager, $json); $this->rateFactory = $rateFactory; $this->classModelFactory = $classModelFactory; $this->ruleFactory = $ruleFactory; + $this->log = $log; } /** * @param array|null $data */ - protected function processData($data = null) + public function execute($data = null) { //Check Row Data exists if (!isset($data[0])) { diff --git a/Component/TieredPrices.php b/Component/TieredPrices.php index 82170dc..a916d91 100644 --- a/Component/TieredPrices.php +++ b/Component/TieredPrices.php @@ -2,12 +2,11 @@ namespace CtiDigital\Configurator\Component; -use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\Serialize\Serializer\Json; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Api\LoggerInterface; use CtiDigital\Configurator\Component\Product\AttributeOption; -use FireGento\FastSimpleImport\Model\ImporterFactory; use CtiDigital\Configurator\Exception\ComponentException; +use FireGento\FastSimpleImport\Model\ImporterFactory; /** * Class Products @@ -15,7 +14,7 @@ * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class TieredPrices extends ComponentAbstract +class TieredPrices implements ComponentInterface { const SKU_COLUMN_HEADING = 'sku'; const SEPARATOR = ';'; @@ -34,6 +33,11 @@ class TieredPrices extends ComponentAbstract */ protected $attributeOption; + /** + * @var LoggerInterface + */ + private $log; + /** * @var [] */ @@ -50,23 +54,19 @@ class TieredPrices extends ComponentAbstract private $skuColumn; /** - * Products constructor. - * - * @param LoggerInterface $log - * @param ObjectManagerInterface $objectManager + * TieredPrices constructor. * @param ImporterFactory $importerFactory * @param AttributeOption $attributeOption + * @param LoggerInterface $log */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, ImporterFactory $importerFactory, - AttributeOption $attributeOption + AttributeOption $attributeOption, + LoggerInterface $log ) { - parent::__construct($log, $objectManager, $json); $this->importerFactory = $importerFactory; $this->attributeOption = $attributeOption; + $this->log = $log; } /** @@ -75,7 +75,7 @@ public function __construct( * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ - protected function processData($data = null) + public function execute($data = null) { // Get the first row of the CSV file for the attribute columns. if (!isset($data[0])) { @@ -121,6 +121,7 @@ protected function processData($data = null) $import->setMultipleValueSeparator(self::SEPARATOR); $import->processImport($pricesArray); } catch (\Exception $e) { + $this->log->logError($e->getMessage()); } $this->log->logInfo($import->getLogTrace()); $this->log->logError($import->getErrorMessages()); @@ -134,7 +135,7 @@ protected function processData($data = null) */ public function getAttributesFromCsv($data = null) { - $attributes = array(); + $attributes = []; foreach ($data[0] as $attributeCode) { $attributes[] = $attributeCode; } diff --git a/Component/Websites.php b/Component/Websites.php index e2416fa..15e42f1 100644 --- a/Component/Websites.php +++ b/Component/Websites.php @@ -2,9 +2,8 @@ namespace CtiDigital\Configurator\Component; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Api\LoggerInterface; -use Magento\Framework\Serialize\Serializer\Json; -use Magento\Framework\ObjectManagerInterface; use CtiDigital\Configurator\Exception\ComponentException; use Magento\Store\Model\Group; use Magento\Store\Model\GroupFactory; @@ -14,11 +13,9 @@ use Magento\Store\Model\WebsiteFactory; use Magento\Indexer\Model\IndexerFactory; use Magento\Framework\Event\ManagerInterface; -use Symfony\Component\Yaml\Yaml; -class Websites extends ComponentAbstract +class Websites implements ComponentInterface { - protected $alias = 'websites'; protected $name = 'Websites'; protected $description = 'Component to manage Websites, Stores and Store Views'; @@ -44,36 +41,41 @@ class Websites extends ComponentAbstract */ protected $groupFactory; + /** + * @var LoggerInterface + */ + private $log; + + /** + * Websites constructor. + * @param IndexerFactory $indexerFactory + * @param ManagerInterface $eventManager + * @param WebsiteFactory $websiteFactory + * @param StoreFactory $storeFactory + * @param GroupFactory $groupFactory + * @param LoggerInterface $log + */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, IndexerFactory $indexerFactory, ManagerInterface $eventManager, WebsiteFactory $websiteFactory, StoreFactory $storeFactory, - GroupFactory $groupFactory + GroupFactory $groupFactory, + LoggerInterface $log ) { - parent::__construct($log, $objectManager, $json); - $this->indexer = $indexerFactory; $this->eventManager = $eventManager; $this->websiteFactory = $websiteFactory; $this->storeFactory = $storeFactory; $this->groupFactory = $groupFactory; + $this->log = $log; } - - protected function processData($data = null) + public function execute($data = null) { try { if (!isset($data['websites'])) { - throw new ComponentException( - sprintf( - "No websites found. Are you sure this component '%s' should be enabled?", - $this->getComponentAlias() - ) - ); + throw new ComponentException("No websites found."); } // Loop through the websites diff --git a/Component/Widgets.php b/Component/Widgets.php index af57c12..be86497 100644 --- a/Component/Widgets.php +++ b/Component/Widgets.php @@ -2,39 +2,70 @@ namespace CtiDigital\Configurator\Component; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Api\LoggerInterface; -use Magento\Framework\Serialize\Serializer\Json; -use Magento\Framework\ObjectManagerInterface; use CtiDigital\Configurator\Exception\ComponentException; use Magento\Widget\Model\ResourceModel\Widget\Instance\Collection as WidgetCollection; +use Magento\Widget\Model\Widget\Instance; +use Magento\Widget\Model\Widget\InstanceFactory as WidgetInstanceFactory; use Magento\Theme\Model\ResourceModel\Theme\Collection as ThemeCollection; use Magento\Store\Model\StoreFactory; -class Widgets extends ComponentAbstract +class Widgets implements ComponentInterface { protected $alias = 'widgets'; protected $name = 'Widgets'; protected $description = 'Component to manage CMS Widgets'; - protected $widgetCollection; - protected $themeCollection; - protected $storeFactory; + /** + * @var WidgetCollection + */ + private $widgetCollection; + + /** + * @var WidgetInstanceFactory + */ + private $widgetInstanceFactory; + + /** + * @var ThemeCollection + */ + private $themeCollection; + + /** + * @var StoreFactory + */ + private $storeFactory; + + /** + * @var LoggerInterface + */ + private $log; + + /** + * Widgets constructor. + * @param WidgetCollection $collection + * @param WidgetInstanceFactory $widgetInstanceFactory + * @param StoreFactory $storeFactory + * @param ThemeCollection $themeCollection + * @param LoggerInterface $log + */ public function __construct( - LoggerInterface $log, - ObjectManagerInterface $objectManager, - Json $json, WidgetCollection $collection, + WidgetInstanceFactory $widgetInstanceFactory, StoreFactory $storeFactory, - ThemeCollection $themeCollection + ThemeCollection $themeCollection, + LoggerInterface $log ) { - parent::__construct($log, $objectManager, $json); $this->widgetCollection = $collection; + $this->widgetInstanceFactory = $widgetInstanceFactory; $this->themeCollection = $themeCollection; $this->storeFactory = $storeFactory; + $this->log = $log; } - protected function processData($data = null) + public function execute($data = null) { try { foreach ($data as $widgetData) { @@ -53,9 +84,12 @@ public function processWidget($widgetData) $widget = $this->findWidgetByInstanceTypeAndTitle($widgetData['instance_type'], $widgetData['title']); $canSave = false; - if (is_null($widget)) { + if ($widget === null) { $canSave = true; - $widget = $this->objectManager->create(\Magento\Widget\Model\Widget\Instance::class); + /** + * @var Instance $widget + */ + $widget = $this->widgetInstanceFactory->create(); } foreach ($widgetData as $key => $value) { @@ -99,7 +133,7 @@ public function validateInstanceType($instanceType) { $this->log->logComment(sprintf("Checking if %s is a valid instance", $instanceType)); $instanceType = '\\' . $instanceType; - $instance = $this->objectManager->create($instanceType); + $instance = $this->widgetInstanceFactory->create($instanceType); if (!$instance instanceof $instanceType) { throw new ComponentException("Instance %s is invalid", $instanceType); } @@ -128,7 +162,6 @@ public function getWidgetByInstanceTypeAndTitle($widgetInstanceType, $widgetTitl ->load(); // @todo add store filter - // If we have more than 1, throw an exception for now. Needs store filter to drill down the widgets further // into a single widget. if ($widgets->count() > 1) { @@ -188,7 +221,6 @@ public function getThemeId($themeCode) */ public function populateWidgetParameters(array $parameters) { - // Default property return return serialize($parameters); } @@ -199,7 +231,7 @@ public function populateWidgetParameters(array $parameters) */ public function getCommaSeparatedStoreIds($stores) { - $storeIds = array(); + $storeIds = []; foreach ($stores as $code) { $storeView = $this->storeFactory->create(); $storeView->load($code, 'code'); From c6f6fd08214f78bd80f6d1d3c2bef01d35e48618 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 08:46:49 +0000 Subject: [PATCH 26/51] Add a new interface which allows the component to receive the source file rather than the data. --- Api/FileComponentInterface.php | 7 +++++++ Component/TaxRates.php | 16 +++++----------- Model/Processor.php | 5 ++++- 3 files changed, 16 insertions(+), 12 deletions(-) create mode 100644 Api/FileComponentInterface.php diff --git a/Api/FileComponentInterface.php b/Api/FileComponentInterface.php new file mode 100644 index 0000000..2c098bf --- /dev/null +++ b/Api/FileComponentInterface.php @@ -0,0 +1,7 @@ +source; + $filePath = BP . '/' . $data; $this->log->logInfo( sprintf('"%s" is being imported', $filePath) ); diff --git a/Model/Processor.php b/Model/Processor.php index e95aadf..965a98d 100644 --- a/Model/Processor.php +++ b/Model/Processor.php @@ -3,6 +3,7 @@ namespace CtiDigital\Configurator\Model; use CtiDigital\Configurator\Api\ComponentInterface; +use CtiDigital\Configurator\Api\FileComponentInterface; use CtiDigital\Configurator\Api\LoggerInterface; use CtiDigital\Configurator\Component\ComponentAbstract; use CtiDigital\Configurator\Exception\ComponentException; @@ -189,7 +190,9 @@ public function runComponent($componentAlias, $componentConfig) if (isset($componentConfig['sources'])) { foreach ($componentConfig['sources'] as $source) { - $sourceData = $this->parseData($source, $sourceType); + $sourceData = ($component instanceof FileComponentInterface) ? + $source : + $this->parseData($source, $sourceType); $component->execute($sourceData); } } From b3ab0b15ecf982b3e8db5cc790615a30700af572 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 09:34:55 +0000 Subject: [PATCH 27/51] Add getAlias and getDescription methods. --- Api/ComponentInterface.php | 10 ++++++ Component/AdminRoles.php | 16 ++++++++++ Component/AdminUsers.php | 16 ++++++++++ Component/ApiIntegrations.php | 16 ++++++++++ Component/AttributeSets.php | 16 ++++++++++ Component/Attributes.php | 16 ++++++++++ Component/Blocks.php | 16 ++++++++++ Component/CatalogPriceRules.php | 16 ++++++++++ Component/Categories.php | 16 ++++++++++ Component/Config.php | 16 ++++++++++ Component/CustomerAttributes.php | 21 +++++++++--- Component/CustomerGroups.php | 16 ++++++++++ Component/Customers.php | 16 ++++++++++ Component/Media.php | 16 ++++++++++ Component/Pages.php | 16 ++++++++++ Component/ProductLinks.php | 16 ++++++++++ Component/Products.php | 16 ++++++++++ Component/ReviewRating.php | 18 +++++++++++ Component/Rewrites.php | 16 ++++++++++ Component/ShippingTableRates.php | 16 ++++++++++ Component/Sql.php | 16 ++++++++++ Component/TaxRates.php | 16 ++++++++++ Component/TaxRules.php | 16 ++++++++++ Component/TieredPrices.php | 16 ++++++++++ Component/Websites.php | 16 ++++++++++ Component/Widgets.php | 16 ++++++++++ Console/Command/ListCommand.php | 5 +-- Test/Unit/Console/Command/ListCommandTest.php | 2 +- Test/Unit/ProcessorTest.php | 32 +++++++++---------- 29 files changed, 433 insertions(+), 23 deletions(-) diff --git a/Api/ComponentInterface.php b/Api/ComponentInterface.php index b974197..d4d8513 100644 --- a/Api/ComponentInterface.php +++ b/Api/ComponentInterface.php @@ -9,4 +9,14 @@ interface ComponentInterface * @return void */ public function execute($data); + + /** + * @return string + */ + public function getAlias(); + + /** + * @return string + */ + public function getDescription(); } diff --git a/Component/AdminRoles.php b/Component/AdminRoles.php index 8e22e69..0c0abf6 100644 --- a/Component/AdminRoles.php +++ b/Component/AdminRoles.php @@ -134,4 +134,20 @@ private function setResourceIds($role, array $resources = null) sprintf('Admin Role "%s" Resources are empty, please check your yaml file', $roleName) ); } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/AdminUsers.php b/Component/AdminUsers.php index 40c3a74..78e34bb 100644 --- a/Component/AdminUsers.php +++ b/Component/AdminUsers.php @@ -172,4 +172,20 @@ private function dataValidator($userData) return true; } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/ApiIntegrations.php b/Component/ApiIntegrations.php index 7a33a83..4d11204 100644 --- a/Component/ApiIntegrations.php +++ b/Component/ApiIntegrations.php @@ -170,4 +170,20 @@ private function activateAndAuthorize($consumerId) $token->setType('access'); $token->save(); } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/AttributeSets.php b/Component/AttributeSets.php index 92931b2..486e417 100644 --- a/Component/AttributeSets.php +++ b/Component/AttributeSets.php @@ -179,4 +179,20 @@ protected function getAttributeSetId($attributeSetName) throw new ComponentException('Could not find attribute set name.'); } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/Attributes.php b/Component/Attributes.php index 00dd8a3..72692ff 100644 --- a/Component/Attributes.php +++ b/Component/Attributes.php @@ -261,4 +261,20 @@ private function manageAttributeOptions($attributeCode, $option) return $optionsToAdd; } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/Blocks.php b/Component/Blocks.php index 09a777f..03471a5 100644 --- a/Component/Blocks.php +++ b/Component/Blocks.php @@ -224,4 +224,20 @@ private function getStoreByCode($code) return $store; } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/CatalogPriceRules.php b/Component/CatalogPriceRules.php index a3350f3..99e3d2d 100644 --- a/Component/CatalogPriceRules.php +++ b/Component/CatalogPriceRules.php @@ -75,4 +75,20 @@ public function execute($data = null) ->setConfig($config) ->process(); } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/Categories.php b/Component/Categories.php index 7c3777a..76fc751 100644 --- a/Component/Categories.php +++ b/Component/Categories.php @@ -204,4 +204,20 @@ private function getStoreGroup($data) } return 'Main Website Store'; } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/Config.php b/Component/Config.php index e244c7d..721fc75 100644 --- a/Component/Config.php +++ b/Component/Config.php @@ -284,4 +284,20 @@ private function encrypt($value) { return $this->encryptor->encrypt($value); } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/CustomerAttributes.php b/Component/CustomerAttributes.php index 3636bb2..fecb0a1 100644 --- a/Component/CustomerAttributes.php +++ b/Component/CustomerAttributes.php @@ -2,14 +2,11 @@ namespace CtiDigital\Configurator\Component; -use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Api\LoggerInterface; -use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Exception\ComponentException; use Magento\Customer\Model\Customer; use Magento\Eav\Setup\EavSetup; use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\ObjectManagerInterface; use Magento\Eav\Model\AttributeRepository; use Magento\Customer\Setup\CustomerSetupFactory; use Magento\Customer\Setup\CustomerSetup; @@ -20,7 +17,7 @@ * @package CtiDigital\Configurator\Model\Component * @SuppressWarnings(PHPMD.LongVariable) */ -class CustomerAttributes implements ComponentInterface +class CustomerAttributes extends Attributes { const DEFAULT_ATTRIBUTE_SET_ID = 1; const DEFAULT_ATTRIBUTE_GROUP_ID = 1; @@ -145,4 +142,20 @@ protected function addAdditionalValues($attributeCode, $attributeConfiguration) )); } } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/CustomerGroups.php b/Component/CustomerGroups.php index 431ffd1..ef98d58 100644 --- a/Component/CustomerGroups.php +++ b/Component/CustomerGroups.php @@ -122,4 +122,20 @@ private function getTaxClassIdFromName($taxClassName) return $taxclassId; } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/Customers.php b/Component/Customers.php index 27d5fe9..8396125 100644 --- a/Component/Customers.php +++ b/Component/Customers.php @@ -225,4 +225,20 @@ private function reindex() $customerGrid->load('customer_grid'); $customerGrid->reindexAll(); } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/Media.php b/Component/Media.php index 378fca2..3996d2d 100644 --- a/Component/Media.php +++ b/Component/Media.php @@ -134,4 +134,20 @@ private function downloadAndSetFile($path, $node, $nest) file_put_contents($path, $fileContents); $this->log->logInfo(sprintf('Created new file: %s', $path), $nest); } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/Pages.php b/Component/Pages.php index 290b3d4..947e5e3 100644 --- a/Component/Pages.php +++ b/Component/Pages.php @@ -200,4 +200,20 @@ protected function setDefaultFields(&$pageData) } } } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/ProductLinks.php b/Component/ProductLinks.php index 6bca593..42bc41d 100644 --- a/Component/ProductLinks.php +++ b/Component/ProductLinks.php @@ -151,4 +151,20 @@ private function doesProductExist($sku) } return false; } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/Products.php b/Component/Products.php index d4ecdf2..6825cc7 100644 --- a/Component/Products.php +++ b/Component/Products.php @@ -422,4 +422,20 @@ public function getSkuColumnIndex($headers) { return array_search(self::SKU_COLUMN_HEADING, $headers); } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/ReviewRating.php b/Component/ReviewRating.php index 5352f99..e7371c1 100644 --- a/Component/ReviewRating.php +++ b/Component/ReviewRating.php @@ -25,6 +25,8 @@ class ReviewRating implements ComponentInterface protected $name = 'Review Rating'; + protected $description = 'Component to create review ratings'; + protected $entityId; /** @@ -231,4 +233,20 @@ private function getReviewEntityId() } return $this->entityId; } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/Rewrites.php b/Component/Rewrites.php index 6b59959..d55fa79 100644 --- a/Component/Rewrites.php +++ b/Component/Rewrites.php @@ -175,4 +175,20 @@ public function extractCsvDataIntoArray($attributeKeys, $rewriteDataCsvRow, $rew } return $rewriteArray; } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/ShippingTableRates.php b/Component/ShippingTableRates.php index 22cc556..c6d01b3 100644 --- a/Component/ShippingTableRates.php +++ b/Component/ShippingTableRates.php @@ -153,4 +153,20 @@ private function removeYamlKeysFromDatabaseInsert(array &$shippingRate) unset($shippingRate['dest_region_code']); unset($shippingRate['website_code']); } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/Sql.php b/Component/Sql.php index e2d91f3..59168cf 100644 --- a/Component/Sql.php +++ b/Component/Sql.php @@ -78,4 +78,20 @@ public function execute($data = null) $this->processor->process($name, $path); } } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/TaxRates.php b/Component/TaxRates.php index a619fea..12dbd96 100755 --- a/Component/TaxRates.php +++ b/Component/TaxRates.php @@ -57,4 +57,20 @@ public function execute($data = null) $this->log->logError($e->getMessage()); } } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/TaxRules.php b/Component/TaxRules.php index b94e558..11a07cb 100644 --- a/Component/TaxRules.php +++ b/Component/TaxRules.php @@ -238,4 +238,20 @@ private function createTaxRule(array $ruleData) sprintf('Tax Rule "%s" created.', $ruleData['code']) ); } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/TieredPrices.php b/Component/TieredPrices.php index a916d91..4332787 100644 --- a/Component/TieredPrices.php +++ b/Component/TieredPrices.php @@ -153,4 +153,20 @@ public function getSkuColumnIndex($headers) { return array_search(self::SKU_COLUMN_HEADING, $headers); } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/Websites.php b/Component/Websites.php index 15e42f1..416d228 100644 --- a/Component/Websites.php +++ b/Component/Websites.php @@ -397,4 +397,20 @@ protected function setDefaultStore(Group $storeGroup, $storeGroupData) $this->log->logError($e->getMessage(), $logNest); } } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Component/Widgets.php b/Component/Widgets.php index be86497..b78419e 100644 --- a/Component/Widgets.php +++ b/Component/Widgets.php @@ -242,4 +242,20 @@ public function getCommaSeparatedStoreIds($stores) } return implode(',', $storeIds); } + + /** + * @return string + */ + public function getAlias() + { + return $this->alias; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } } diff --git a/Console/Command/ListCommand.php b/Console/Command/ListCommand.php index e4106b7..f6a3e9a 100644 --- a/Console/Command/ListCommand.php +++ b/Console/Command/ListCommand.php @@ -2,6 +2,7 @@ namespace CtiDigital\Configurator\Console\Command; +use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Model\ComponentList; use CtiDigital\Configurator\Exception\ConfiguratorAdapterException; use CtiDigital\Configurator\Api\ConfigInterface; @@ -56,11 +57,11 @@ protected function execute(InputInterface $input, OutputInterface $output) try { $count = 1; foreach ($this->configInterface->getAllComponents() as $component) { - /* @var \CtiDigital\Configurator\Component\ComponentAbstract $componentClass */ + /* @var ComponentInterface $componentClass */ $componentClass = $this->objectManagerInterface->create($component['class']); $comment = str_pad($count.') ', 4) - . str_pad($componentClass->getComponentAlias(), 20) + . str_pad($componentClass->getAlias(), 20) . ' - ' . $componentClass->getDescription(); $output->writeln('' . $comment . ''); $count++; diff --git a/Test/Unit/Console/Command/ListCommandTest.php b/Test/Unit/Console/Command/ListCommandTest.php index 0baa8a7..af7c9a3 100644 --- a/Test/Unit/Console/Command/ListCommandTest.php +++ b/Test/Unit/Console/Command/ListCommandTest.php @@ -41,7 +41,7 @@ class ListCommandTest extends \PHPUnit\Framework\TestCase /** * @var ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ - private $objectManager = array(); + private $objectManager; protected function setUp() { diff --git a/Test/Unit/ProcessorTest.php b/Test/Unit/ProcessorTest.php index a72fba1..50d95b3 100644 --- a/Test/Unit/ProcessorTest.php +++ b/Test/Unit/ProcessorTest.php @@ -25,7 +25,12 @@ class ProcessorTest extends \PHPUnit\Framework\TestCase /** * @var ComponentFactoryInterface|\PHPUnit_Framework_MockObject_MockObject */ - private $mockComponentFactory; + private $componentFactory; + + /** + * @var State|\PHPUnit\Framework\MockObject\MockObject + */ + private $state; /** * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject @@ -37,7 +42,7 @@ protected function setUp() $this->configInterface = $this->getMockBuilder(ConfigInterface::class) ->disableOriginalConstructor() ->getMock(); - $this->mockComponentFactory = $this->getMockBuilder(ComponentFactory::class) + $this->componentFactory = $this->getMockBuilder(ComponentFactory::class) ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); @@ -48,28 +53,25 @@ protected function setUp() $scopeInterface = $this->getMockBuilder(ScopeInterface::class) ->disableOriginalConstructor() ->getMock(); - $state = $this->getMockBuilder(State::class) + $this->state = $this->getMockBuilder(State::class) ->disableOriginalConstructor() - ->setConstructorArgs(array($scopeInterface)) + ->setConstructorArgs([$scopeInterface]) ->getMock(); $this->loggerInterface = $this->getMockBuilder(LoggerInterface::class) ->disableOriginalConstructor() - ->setConstructorArgs(array($consoleOutput)) + ->setConstructorArgs([$consoleOutput]) ->getMock(); - $this->processor = $this->getMockBuilder(Processor::class) - ->disableOriginalConstructor() - ->setConstructorArgs(array( - $this->configInterface, - $this->loggerInterface, - $state, - $this->mockComponentFactory, - ))->getMock(); + $this->processor = new Processor( + $this->configInterface, + $this->loggerInterface, + $this->state, + $this->componentFactory + ); } public function testICanSetAnEnvironment() { - $this->markTestSkipped("To do - Test we can set environments"); $environment = 'stage'; $this->processor->setEnvironment($environment); $this->assertEquals($environment, $this->processor->getEnvironment()); @@ -77,7 +79,6 @@ public function testICanSetAnEnvironment() public function testICanAddASingleComponent() { - $this->markTestSkipped("To do - Test a single component can be added"); $component = 'websites'; $this->processor->addComponent($component); $this->assertArrayHasKey($component, $this->processor->getComponents()); @@ -85,7 +86,6 @@ public function testICanAddASingleComponent() public function testICanAddMultipleComponents() { - $this->markTestSkipped("To do - Test multiple components can be added"); $components = ['website', 'config']; foreach ($components as $component) { $this->processor->addComponent($component); From 780ad1bdb104d1860beb03229b11cc75f1a044e7 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 09:37:54 +0000 Subject: [PATCH 28/51] Fix dependencies in test. --- Test/Unit/Console/Command/RunCommandTest.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/Test/Unit/Console/Command/RunCommandTest.php b/Test/Unit/Console/Command/RunCommandTest.php index a97ea10..6528be9 100644 --- a/Test/Unit/Console/Command/RunCommandTest.php +++ b/Test/Unit/Console/Command/RunCommandTest.php @@ -21,7 +21,6 @@ */ class RunCommandTest extends \PHPUnit\Framework\TestCase { - /** * @var RunCommand */ @@ -37,11 +36,6 @@ class RunCommandTest extends \PHPUnit\Framework\TestCase */ private $mockOutput; - /** - * @var ConfiguratorAdapterInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $runCommandAdapter; - /** * @var ConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ @@ -64,12 +58,6 @@ class RunCommandTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->runCommandAdapter = $this->getMockBuilder(ConfiguratorAdapterInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->configInterface = $this->getMockBuilder(ConfigInterface::class) - ->disableOriginalConstructor() - ->getMock(); $this->componentFactory = $this->getMockBuilder(ComponentFactoryInterface::class) ->disableOriginalConstructor() ->getMock(); @@ -99,8 +87,6 @@ protected function setUp() ->getMock(); $this->command = new RunCommand( - $this->runCommandAdapter, - $this->configInterface, $this->processor ); From b363bc5869e125ba36906fba88b55a63f8897229 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 10:23:43 +0000 Subject: [PATCH 29/51] Load components with di.xml rather than Object Manager. --- Api/ComponentListInterface.php | 17 +++ Component/ComponentList.php | 37 ++++++ Console/Command/ListCommand.php | 36 ++---- Test/Unit/Console/Command/ListCommandTest.php | 81 ------------- Test/Unit/Console/Command/RunCommandTest.php | 110 ------------------ etc/configurator.xml | 30 ----- etc/configurator.xsd | 14 --- etc/di.xml | 34 ++++++ 8 files changed, 98 insertions(+), 261 deletions(-) create mode 100644 Api/ComponentListInterface.php create mode 100644 Component/ComponentList.php delete mode 100644 Test/Unit/Console/Command/ListCommandTest.php delete mode 100644 Test/Unit/Console/Command/RunCommandTest.php delete mode 100644 etc/configurator.xml delete mode 100644 etc/configurator.xsd diff --git a/Api/ComponentListInterface.php b/Api/ComponentListInterface.php new file mode 100644 index 0000000..3168830 --- /dev/null +++ b/Api/ComponentListInterface.php @@ -0,0 +1,17 @@ +components = $components; + } + + /** + * @inheritDoc + */ + public function getComponent($componentAlias) + { + if (array_key_exists($componentAlias, $this->components) === true) { + return $this->components[$componentAlias]; + } + } + + /** + * @inheritDoc + */ + public function getAllComponents() + { + return $this->components; + } +} diff --git a/Console/Command/ListCommand.php b/Console/Command/ListCommand.php index f6a3e9a..fc2a4d8 100644 --- a/Console/Command/ListCommand.php +++ b/Console/Command/ListCommand.php @@ -2,12 +2,8 @@ namespace CtiDigital\Configurator\Console\Command; -use CtiDigital\Configurator\Api\ComponentInterface; -use CtiDigital\Configurator\Model\ComponentList; +use CtiDigital\Configurator\Api\ComponentListInterface; use CtiDigital\Configurator\Exception\ConfiguratorAdapterException; -use CtiDigital\Configurator\Api\ConfigInterface; -use CtiDigital\Configurator\Api\ConfiguratorAdapterInterface; -use Magento\Framework\ObjectManagerInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -15,29 +11,19 @@ class ListCommand extends Command { /** - * @var ConfiguratorAdapterInterface + * @var ComponentListInterface */ - private $configuratorAdapter; + private $componentList; /** - * @var ConfigInterface|CtiDigital\Configurator\Console\Command\ListCommand + * ListCommand constructor. + * @param ComponentListInterface $componentList */ - private $configInterface; - - /** - * @var ObjectManagerInterface - */ - private $objectManagerInterface; - public function __construct( - ConfiguratorAdapterInterface $configuratorAdapter, - ConfigInterface $config, - ObjectManagerInterface $objectManager + ComponentListInterface $componentList ) { parent::__construct(); - $this->objectManagerInterface = $objectManager; - $this->configuratorAdapter = $configuratorAdapter; - $this->configInterface = $config; + $this->componentList = $componentList; } protected function configure() @@ -56,13 +42,11 @@ protected function execute(InputInterface $input, OutputInterface $output) { try { $count = 1; - foreach ($this->configInterface->getAllComponents() as $component) { - /* @var ComponentInterface $componentClass */ - $componentClass = $this->objectManagerInterface->create($component['class']); + foreach ($this->componentList->getAllComponents() as $component) { $comment = str_pad($count.') ', 4) - . str_pad($componentClass->getAlias(), 20) - . ' - ' . $componentClass->getDescription(); + . str_pad($component->getAlias(), 20) + . ' - ' . $component->getDescription(); $output->writeln('' . $comment . ''); $count++; } diff --git a/Test/Unit/Console/Command/ListCommandTest.php b/Test/Unit/Console/Command/ListCommandTest.php deleted file mode 100644 index af7c9a3..0000000 --- a/Test/Unit/Console/Command/ListCommandTest.php +++ /dev/null @@ -1,81 +0,0 @@ -listCommandAdapter = $this->getMockBuilder(ConfiguratorAdapterInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->configInterface = $this->getMockBuilder(ConfigInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->objectManager = $this->getMockBuilder(ObjectManagerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->command = new ListCommand( - $this->listCommandAdapter, - $this->configInterface, - $this->objectManager - ); - - $this->mockInput = $this->getMockBuilder(InputInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->mockOutput = $this->getMockBuilder(OutputInterface::class) - ->disableOriginalConstructor() - ->getMocK(); - } - - public function testItIsAConsoleCommand() - { - $this->assertInstanceOf(Command::class, $this->command); - } - - public function testItHasTheCorrectName() - { - $this->assertSame('configurator:list', $this->command->getName()); - } -} diff --git a/Test/Unit/Console/Command/RunCommandTest.php b/Test/Unit/Console/Command/RunCommandTest.php deleted file mode 100644 index 6528be9..0000000 --- a/Test/Unit/Console/Command/RunCommandTest.php +++ /dev/null @@ -1,110 +0,0 @@ -componentFactory = $this->getMockBuilder(ComponentFactoryInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $consoleOutput = $this->getMockBuilder(ConsoleOutputInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $scopeInterface = $this->getMockBuilder(ScopeInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $state = $this->getMockBuilder(State::class) - ->disableOriginalConstructor() - ->setConstructorArgs([$scopeInterface]) - ->getMock(); - $this->loggerInterface = $this->getMockBuilder(LoggerInterface::class) - ->disableOriginalConstructor() - ->setConstructorArgs([$consoleOutput]) - ->getMock(); - - $this->processor = $this->getMockBuilder(Processor::class) - ->disableOriginalConstructor() - ->setConstructorArgs([ - $this->configInterface, - $this->loggerInterface, - $state, - $this->componentFactory - ]) - ->getMock(); - - $this->command = new RunCommand( - $this->processor - ); - - $this->mockInput = $this->getMockBuilder(InputInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->mockOutput = $this->getMockBuilder(OutputInterface::class) - ->disableOriginalConstructor() - ->getMock(); - } - - public function testItIsAConsoleCommand() - { - $this->assertInstanceOf(Command::class, $this->command); - } - - public function testItHasTheCorrectName() - { - $this->assertSame('configurator:run', $this->command->getName()); - } -} diff --git a/etc/configurator.xml b/etc/configurator.xml deleted file mode 100644 index 5ef69dc..0000000 --- a/etc/configurator.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/etc/configurator.xsd b/etc/configurator.xsd deleted file mode 100644 index b83813b..0000000 --- a/etc/configurator.xsd +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/etc/di.xml b/etc/di.xml index fbb32a2..e552d03 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -7,6 +7,8 @@ type="CtiDigital\Configurator\Model\Configurator\Config" /> + @@ -17,6 +19,38 @@ + + + + CtiDigital\Configurator\Component\Websites + CtiDigital\Configurator\Component\Config + CtiDigital\Configurator\Component\Attributes + CtiDigital\Configurator\Component\AttributeSets + CtiDigital\Configurator\Component\AdminRoles + CtiDigital\Configurator\Component\AdminUsers + CtiDigital\Configurator\Component\CustomerGroups + CtiDigital\Configurator\Component\Categories + CtiDigital\Configurator\Component\TaxRates + CtiDigital\Configurator\Component\TaxRules + CtiDigital\Configurator\Component\Products + CtiDigital\Configurator\Component\Blocks + CtiDigital\Configurator\Component\Pages + CtiDigital\Configurator\Component\ApiIntegrations + CtiDigital\Configurator\Component\Widgets + CtiDigital\Configurator\Component\Media + CtiDigital\Configurator\Component\Rewrites + CtiDigital\Configurator\Component\ReviewRating + CtiDigital\Configurator\Component\ProductLinks + CtiDigital\Configurator\Component\Customers + CtiDigital\Configurator\Component\CatalogPriceRules + CtiDigital\Configurator\Component\Sql + CtiDigital\Configurator\Component\ShippingTableRates + CtiDigital\Configurator\Component\CustomerAttributes + CtiDigital\Configurator\Component\TieredPrices + + + + Magento\Framework\Module\Setup\Context From cfb18aa104d05ec904af941a0c8ca7283f72ed56 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 10:58:26 +0000 Subject: [PATCH 30/51] Remove component factory as components are loaded differently now. --- Api/ComponentListInterface.php | 2 +- Component/ComponentList.php | 1 + Component/Factory/ComponentFactory.php | 43 ---------- .../Factory/ComponentFactoryInterface.php | 24 ------ Console/Command/RunCommand.php | 6 +- Model/Processor.php | 79 ++++++++----------- etc/di.xml | 5 -- 7 files changed, 37 insertions(+), 123 deletions(-) delete mode 100644 Component/Factory/ComponentFactory.php delete mode 100644 Component/Factory/ComponentFactoryInterface.php diff --git a/Api/ComponentListInterface.php b/Api/ComponentListInterface.php index 3168830..f233857 100644 --- a/Api/ComponentListInterface.php +++ b/Api/ComponentListInterface.php @@ -6,7 +6,7 @@ interface ComponentListInterface { /** * @param $componentAlias - * @return ComponentInterface + * @return ComponentInterface|bool */ public function getComponent($componentAlias); diff --git a/Component/ComponentList.php b/Component/ComponentList.php index f1e7fd7..cc0b93e 100644 --- a/Component/ComponentList.php +++ b/Component/ComponentList.php @@ -25,6 +25,7 @@ public function getComponent($componentAlias) if (array_key_exists($componentAlias, $this->components) === true) { return $this->components[$componentAlias]; } + return false; } /** diff --git a/Component/Factory/ComponentFactory.php b/Component/Factory/ComponentFactory.php deleted file mode 100644 index 2eb88ac..0000000 --- a/Component/Factory/ComponentFactory.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright 2017 CtiDigital - */ - -namespace CtiDigital\Configurator\Component\Factory; - -use CtiDigital\Configurator\Component\ComponentAbstract; -use Magento\Framework\ObjectManagerInterface; - -/** - * Class ComponentFactory - */ -class ComponentFactory implements ComponentFactoryInterface -{ - /** - * @var ObjectManagerInterface - */ - private $objectManager; - - /** - * ComponentFactory constructor. - * - * @param ObjectManagerInterface $objectManager - */ - public function __construct(ObjectManagerInterface $objectManager) - { - $this->objectManager = $objectManager; - } - - /** - * @param string $componentClass - * @param array $args - * - * @return ComponentAbstract - */ - public function create($componentClass, array $args = []) - { - return $this->objectManager->create($componentClass, $args); - } -} diff --git a/Component/Factory/ComponentFactoryInterface.php b/Component/Factory/ComponentFactoryInterface.php deleted file mode 100644 index 1548890..0000000 --- a/Component/Factory/ComponentFactoryInterface.php +++ /dev/null @@ -1,24 +0,0 @@ - - * @copyright 2017 CtiDigital - */ - -namespace CtiDigital\Configurator\Component\Factory; - -use CtiDigital\Configurator\Component\ComponentAbstract; - -/** - * Interface ComponentFactoryInterface - */ -interface ComponentFactoryInterface -{ - /** - * @param string $componentClass - * @param array $args - * - * @return ComponentAbstract - */ - public function create($componentClass, array $args = []); -} diff --git a/Console/Command/RunCommand.php b/Console/Command/RunCommand.php index 18ffb5b..3ab7b5d 100644 --- a/Console/Command/RunCommand.php +++ b/Console/Command/RunCommand.php @@ -38,17 +38,17 @@ protected function configure() 'c', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Test', - array() + [] ); $this ->setName('configurator:run') ->setDescription('Run configurator components') ->setDefinition( - new InputDefinition(array( + new InputDefinition([ $environmentOption, $componentOption - )) + ]) ); } diff --git a/Model/Processor.php b/Model/Processor.php index 965a98d..e50e1e2 100644 --- a/Model/Processor.php +++ b/Model/Processor.php @@ -4,11 +4,9 @@ use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Api\FileComponentInterface; +use CtiDigital\Configurator\Api\ComponentListInterface; use CtiDigital\Configurator\Api\LoggerInterface; -use CtiDigital\Configurator\Component\ComponentAbstract; use CtiDigital\Configurator\Exception\ComponentException; -use CtiDigital\Configurator\Api\ConfigInterface; -use CtiDigital\Configurator\Component\Factory\ComponentFactoryInterface; use Symfony\Component\Yaml\Parser; use Magento\Framework\App\State; use Magento\Framework\App\Area; @@ -26,19 +24,14 @@ class Processor protected $environment; /** - * @var array + * @var [] */ - protected $components = array(); + protected $components = []; /** - * @var ConfigInterface + * @var ComponentListInterface */ - protected $configInterface; - - /** - * @var LoggerInterface - */ - protected $log; + protected $componentList; /** * @var State @@ -46,28 +39,24 @@ class Processor protected $state; /** - * @var ComponentFactoryInterface + * @var LoggerInterface */ - protected $componentFactory; + protected $log; /** * Processor constructor. - * - * @param ConfigInterface $configInterface - * @param ComponentFactoryInterface $componentFactory - * @param LoggerInterface $logging + * @param ComponentListInterface $componentList * @param State $state + * @param LoggerInterface $logging */ public function __construct( - ConfigInterface $configInterface, - LoggerInterface $logging, + ComponentListInterface $componentList, State $state, - ComponentFactoryInterface $componentFactory + LoggerInterface $logging ) { - $this->log = $logging; - $this->configInterface = $configInterface; + $this->componentList = $componentList; $this->state = $state; - $this->componentFactory = $componentFactory; + $this->log = $logging; } public function getLogger() @@ -181,10 +170,8 @@ public function runComponent($componentAlias, $componentConfig) $this->log->logComment(sprintf("| Loading component %s |", $componentAlias)); $this->log->logComment(str_pad("----------------------", (22 + strlen($componentAlias)), "-")); - $componentClass = $this->configInterface->getComponentByName($componentAlias); - /* @var ComponentInterface $component */ - $component = $this->componentFactory->create($componentClass); + $component = $this->componentList->getComponent($componentAlias); $sourceType = (isset($componentConfig['type']) === true) ? $componentConfig['type'] : null; @@ -247,10 +234,12 @@ private function getMasterYaml() { // Read master yaml $masterPath = BP . '/app/etc/master.yaml'; + // phpcs:ignore Magento2.Functions.DiscouragedFunction if (!file_exists($masterPath)) { throw new ComponentException("Master YAML does not exist. Please create one in $masterPath"); } $this->log->logComment(sprintf("Found Master YAML")); + // phpcs:ignore Magento2.Functions.DiscouragedFunction $yamlContents = file_get_contents($masterPath); $yaml = new Parser(); $master = $yaml->parse($yamlContents); @@ -272,15 +261,8 @@ private function isValidComponent($componentName) if ($this->log->getLogLevel() > \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL) { $this->log->logQuestion(sprintf("Does the %s component exist?", $componentName)); } - $componentClass = $this->configInterface->getComponentByName($componentName); + $component = $this->componentList->getComponent($componentName); - if (!$componentClass) { - $this->log->logError(sprintf("The %s component has no class name.", $componentName)); - return false; - } - - $this->log->logComment(sprintf("The %s component has %s class name.", $componentName, $componentClass)); - $component = $this->componentFactory->create($componentClass); if ($component instanceof ComponentInterface) { return true; } @@ -303,26 +285,29 @@ private function validateMasterYaml($master) sprintf('It appears %s does not have a "enabled" node. This is required.', $componentAlias) ); } - // Check it has at least 1 data source - $sourceCount = 0; - if (isset($componentConfig['sources'])) { - foreach ($componentConfig['sources'] as $i => $source) { - $sourceCount++; - } + $componentHasSource = false; + + if (isset($componentConfig['sources']) && + is_array($componentConfig['sources']) && + count($componentConfig['sources']) > 0 === true + ) { + $componentHasSource = true; } - if (isset($componentConfig['env'])) { + if (isset($componentConfig['env']) === true) { foreach ($componentConfig['env'] as $envData) { - if (isset($envData['sources'])) { - foreach ($envData['sources'] as $i => $source) { - $sourceCount++; - } + if (isset($envData['sources']) && + is_array($envData['sources']) && + count($envData['sources']) > 0 === true + ) { + $componentHasSource = true; + break; } } } - if ($sourceCount < 1) { + if ($componentHasSource === false) { throw new ComponentException( sprintf('It appears there are no data sources for the %s component.', $componentAlias) ); diff --git a/etc/di.xml b/etc/di.xml index e552d03..fd7d382 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -63,11 +63,6 @@ - - - CtiDigital\Configurator\Component\Factory\ComponentFactory - - CtiDigital\Configurator\Component\CatalogPriceRules\CatalogPriceRulesProcessor From 1445ccc30729de42783373080c22a010d8808d02 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 12:23:23 +0000 Subject: [PATCH 31/51] Remove tests which didn't test functionality. --- Test/Unit/Component/AdminRolesTest.php | 30 ----- Test/Unit/Component/AdminUsersTest.php | 30 ----- Test/Unit/Component/ApiIntegrationsTest.php | 45 ------- Test/Unit/Component/AttributeSetsTest.php | 36 ------ Test/Unit/Component/AttributesTest.php | 27 ---- Test/Unit/Component/BlocksTest.php | 19 --- Test/Unit/Component/CatalogPriceRulesTest.php | 33 +++-- .../Component/ComponentAbstractTestCase.php | 99 --------------- Test/Unit/Component/ConfigTest.php | 119 ++++++++++------- Test/Unit/Component/CustomerGroupsTest.php | 29 ----- Test/Unit/Component/CustomersTest.php | 120 +++++++++++------- Test/Unit/Component/MediaTest.php | 18 --- Test/Unit/Component/PagesTest.php | 40 ------ Test/Unit/Component/ProductLinksTest.php | 25 ---- Test/Unit/Component/ProductsTest.php | 94 +++++++++----- Test/Unit/Component/ReviewRatingTest.php | 117 +++++++++-------- Test/Unit/Component/RewritesTest.php | 29 ----- Test/Unit/Component/SqlTest.php | 26 ---- Test/Unit/Component/TaxRatesTest.php | 24 ---- Test/Unit/Component/TaxRulesTest.php | 33 ----- Test/Unit/Component/WebsitesTest.php | 41 ------ Test/Unit/Component/WidgetsTest.php | 34 ----- Test/Unit/Processor/SqlSplitProcessorTest.php | 1 + Test/Unit/ProcessorTest.php | 29 ++--- 24 files changed, 301 insertions(+), 797 deletions(-) delete mode 100644 Test/Unit/Component/AdminRolesTest.php delete mode 100644 Test/Unit/Component/AdminUsersTest.php delete mode 100644 Test/Unit/Component/ApiIntegrationsTest.php delete mode 100644 Test/Unit/Component/AttributeSetsTest.php delete mode 100644 Test/Unit/Component/AttributesTest.php delete mode 100644 Test/Unit/Component/BlocksTest.php delete mode 100644 Test/Unit/Component/ComponentAbstractTestCase.php delete mode 100644 Test/Unit/Component/CustomerGroupsTest.php delete mode 100644 Test/Unit/Component/MediaTest.php delete mode 100644 Test/Unit/Component/PagesTest.php delete mode 100644 Test/Unit/Component/ProductLinksTest.php delete mode 100644 Test/Unit/Component/RewritesTest.php delete mode 100644 Test/Unit/Component/SqlTest.php delete mode 100755 Test/Unit/Component/TaxRatesTest.php delete mode 100644 Test/Unit/Component/TaxRulesTest.php delete mode 100644 Test/Unit/Component/WebsitesTest.php delete mode 100644 Test/Unit/Component/WidgetsTest.php diff --git a/Test/Unit/Component/AdminRolesTest.php b/Test/Unit/Component/AdminRolesTest.php deleted file mode 100644 index 5c13f6d..0000000 --- a/Test/Unit/Component/AdminRolesTest.php +++ /dev/null @@ -1,30 +0,0 @@ -getMockBuilder(RoleFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $rulesFactory = $this->getMockBuilder(RulesFactory::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->component = new AdminRoles( - $this->logInterface, - $this->objectManager, - $this->json, - $roleFactory, - $rulesFactory - ); - $this->className = AdminRoles::class; - } -} diff --git a/Test/Unit/Component/AdminUsersTest.php b/Test/Unit/Component/AdminUsersTest.php deleted file mode 100644 index bc4e7b3..0000000 --- a/Test/Unit/Component/AdminUsersTest.php +++ /dev/null @@ -1,30 +0,0 @@ -getMockBuilder(UserFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $rulesFactory = $this->getMockBuilder(RoleFactory::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->component = new AdminUsers( - $this->logInterface, - $this->objectManager, - $this->json, - $userFactory, - $rulesFactory - ); - $this->className = AdminUsers::class; - } -} diff --git a/Test/Unit/Component/ApiIntegrationsTest.php b/Test/Unit/Component/ApiIntegrationsTest.php deleted file mode 100644 index 4586fe9..0000000 --- a/Test/Unit/Component/ApiIntegrationsTest.php +++ /dev/null @@ -1,45 +0,0 @@ -getMockBuilder(AuthorizationService::class) - ->disableOriginalConstructor() - ->getMock(); - $integrationFactory = $this->getMockBuilder(IntegrationFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $integrationService = $this->getMockBuilder(IntegrationServiceInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $tokenFactory = $this->getMockBuilder(TokenFactory::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->component = new ApiIntegrations( - $this->logInterface, - $this->objectManager, - $this->json, - $integrationFactory, - $integrationService, - $authorizationService, - $tokenFactory - ); - $this->className = ApiIntegrations::class; - } -} diff --git a/Test/Unit/Component/AttributeSetsTest.php b/Test/Unit/Component/AttributeSetsTest.php deleted file mode 100644 index 2e61a65..0000000 --- a/Test/Unit/Component/AttributeSetsTest.php +++ /dev/null @@ -1,36 +0,0 @@ -getMockBuilder(EavSetup::class) - ->disableOriginalConstructor() - ->getMock(); - $attributeSetsRepositoryInterface = $this->getMockBuilder(AttributeSetRepositoryInterface::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->component = new AttributeSets( - $this->logInterface, - $this->objectManager, - $this->json, - $eavSetup, - $attributeSetsRepositoryInterface - ); - - $this->className = AttributeSets::class; - } -} diff --git a/Test/Unit/Component/AttributesTest.php b/Test/Unit/Component/AttributesTest.php deleted file mode 100644 index 0d97dd0..0000000 --- a/Test/Unit/Component/AttributesTest.php +++ /dev/null @@ -1,27 +0,0 @@ -getMockBuilder(EavSetup::class) - ->disableOriginalConstructor() - ->getMock(); - $attributeRepository = $this->getMockBuilder(AttributeRepositoryInterface::class)->getMock(); - $this->component = new Attributes( - $this->logInterface, - $this->objectManager, - $this->json, - $eavSetup, - $attributeRepository - ); - $this->className = Attributes::class; - } -} diff --git a/Test/Unit/Component/BlocksTest.php b/Test/Unit/Component/BlocksTest.php deleted file mode 100644 index 10909ae..0000000 --- a/Test/Unit/Component/BlocksTest.php +++ /dev/null @@ -1,19 +0,0 @@ -getMockBuilder(BlockInterfaceFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $this->component = new Blocks($this->logInterface, $this->objectManager, $this->json, $blockInterface); - $this->className = Blocks::class; - } -} diff --git a/Test/Unit/Component/CatalogPriceRulesTest.php b/Test/Unit/Component/CatalogPriceRulesTest.php index 7107364..852a77a 100644 --- a/Test/Unit/Component/CatalogPriceRulesTest.php +++ b/Test/Unit/Component/CatalogPriceRulesTest.php @@ -10,40 +10,49 @@ use CtiDigital\Configurator\Api\ComponentProcessorInterface; use CtiDigital\Configurator\Component\CatalogPriceRules; use CtiDigital\Configurator\Component\CatalogPriceRules\CatalogPriceRulesProcessor; +use CtiDigital\Configurator\Api\LoggerInterface; /** * Class CatalogPriceRulesTest * @codingStandardsIgnoreStart * @SuppressWarnings(PHPMD) */ -class CatalogPriceRulesTest extends ComponentAbstractTestCase +class CatalogPriceRulesTest extends \PHPUnit\Framework\TestCase { + /** + * @var CatalogPriceRules + */ + private $catalogPriceRules; + + /** + * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $log; + /** * @var ComponentProcessorInterface|\PHPUnit_Framework_MockObject_MockObject */ private $mockComponentProcessor; - protected function componentSetUp() + protected function setUp() { $this->mockComponentProcessor = $this->getMockBuilder(CatalogPriceRulesProcessor::class) ->disableOriginalConstructor() ->setMethods(['setData', 'setConfig', 'process']) ->getMock(); - $this->component = new CatalogPriceRules( - $this->logInterface, - $this->objectManager, - $this->json, - $this->mockComponentProcessor - ); + $this->log = $this->getMockBuilder(LoggerInterface::class) + ->disableOriginalConstructor() + ->getMock(); - $this->className = CatalogPriceRules::class; + $this->catalogPriceRules = new CatalogPriceRules( + $this->mockComponentProcessor, + $this->log + ); } public function testProcessDataExecution() { - $this->markTestSkipped('Test will be skipped until CI configuration will be fixed'); - $this->mockComponentProcessor->expects($this->once()) ->method('setData') ->willReturn($this->mockComponentProcessor); @@ -55,6 +64,6 @@ public function testProcessDataExecution() $this->mockComponentProcessor->expects($this->once()) ->method('process'); - $this->component->process(); + $this->catalogPriceRules->execute(); } } diff --git a/Test/Unit/Component/ComponentAbstractTestCase.php b/Test/Unit/Component/ComponentAbstractTestCase.php deleted file mode 100644 index 61c1c40..0000000 --- a/Test/Unit/Component/ComponentAbstractTestCase.php +++ /dev/null @@ -1,99 +0,0 @@ -testObjectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->objectManager = $this->getMockBuilder(ObjectManagerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->logInterface = $this->getMockBuilder(LoggerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->json = $this->getMockBuilder(Json::class) - ->disableOriginalConstructor() - ->getMock(); - $this->componentSetUp(); - } - - public function testItExtendsAbstract() - { - $this->assertInstanceOf(ComponentAbstract::class, $this->component); - } - - public function testItHasAnAlias() - { - $this->assertClassHasAttribute('alias', $this->className); - $this->assertNotEmpty( - $this->component->getComponentAlias(), - sprintf('No alias specified in component %s', $this->className) - ); - } - - public function testItHasAName() - { - $this->assertClassHasAttribute('name', $this->className); - $this->assertNotEmpty( - $this->component->getComponentName(), - sprintf('No name specified in component %s', $this->className) - ); - } - - /** - * @param $testSource - * @param $expected - * - * @dataProvider isSourceRemoteDataProvider - */ - public function testIsSourceRemote($testSource, $expected) - { - $this->assertEquals($expected, $this->component->isSourceRemote($testSource)); - } - - /** - * @return array - */ - public static function isSourceRemoteDataProvider() - { - return [ - ['https://www.test.com/remote-source.json', true], - ['../configurator/Configuration/base-website-config.yaml', false], - ['configurator/Configuration/example.csv', false] - ]; - } -} diff --git a/Test/Unit/Component/ConfigTest.php b/Test/Unit/Component/ConfigTest.php index d36c67b..e7ae5a6 100644 --- a/Test/Unit/Component/ConfigTest.php +++ b/Test/Unit/Component/ConfigTest.php @@ -3,25 +3,79 @@ namespace CtiDigital\Configurator\Test\Unit\Component; use CtiDigital\Configurator\Component\Config; +use Magento\Config\Model\ResourceModel\Config as ConfigResource; +use Magento\Framework\App\Config as ScopeConfig; +use Magento\Theme\Model\ResourceModel\Theme\Collection; +use Magento\Theme\Model\ResourceModel\Theme\CollectionFactory; use Magento\Framework\Encryption\EncryptorInterface; +use CtiDigital\Configurator\Api\LoggerInterface; -class ConfigTest extends ComponentAbstractTestCase +class ConfigTest extends \PHPUnit\Framework\TestCase { + /** + * @var Config + */ + private $config; + + /** + * @var ConfigResource|\PHPUnit\Framework\MockObject\MockObject + */ + private $configResource; + + /** + * @var ScopeConfig|\PHPUnit\Framework\MockObject\MockObject + */ + private $scopeConfig; + + /** + * @var Collection|\PHPUnit\Framework\MockObject\MockObject + */ + private $collection; - protected function componentSetUp() + /** + * @var CollectionFactory|\PHPUnit\Framework\MockObject\MockObject + */ + private $collectionFactory; + + /** + * @var EncryptorInterface|\PHPUnit\Framework\MockObject\MockObject + */ + private $encryptorInterface; + + /** + * @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject + */ + private $log; + + protected function setUp() { - $collectionFactory = $this->getMockBuilder('\Magento\Theme\Model\ResourceModel\Theme\CollectionFactory') + $this->configResource = $this->getMockBuilder(ConfigResource::class) ->disableOriginalConstructor() ->getMock(); - $encrypterInterface = $this->getMockBuilder(EncryptorInterface::class)->getMock(); - $this->component = new Config( - $this->logInterface, - $this->objectManager, - $this->json, - $collectionFactory, - $encrypterInterface + $this->scopeConfig = $this->getMockBuilder(ScopeConfig::class) + ->disableOriginalConstructor() + ->getMock(); + $this->collection = $this->getMockBuilder(Collection::class) + ->disableOriginalConstructor() + ->getMock(); + $this->collectionFactory = $this->getMockBuilder(CollectionFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->collectionFactory->expects($this->any())->method('create')->willReturn($this->collection); + $this->encryptorInterface = $this->getMockBuilder(EncryptorInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->log = $this->getMockBuilder(LoggerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->config = new Config( + $this->configResource, + $this->scopeConfig, + $this->collectionFactory, + $this->encryptorInterface, + $this->log ); - $this->className = Config::class; } /** @@ -29,11 +83,7 @@ protected function componentSetUp() */ public function testIsConfigTheme() { - /** - * @var Config $config - */ - $config = $this->testObjectManager->getObject(Config::class); - $this->assertTrue($config->isConfigTheme($config::PATH_THEME_ID, 'theme')); + $this->assertTrue($this->config->isConfigTheme(Config::PATH_THEME_ID, 'theme')); } /** @@ -41,11 +91,7 @@ public function testIsConfigTheme() */ public function testIsConfigThemeWithAnId() { - /** - * @var Config $config - */ - $config = $this->testObjectManager->getObject(Config::class); - $this->assertTrue($config->isConfigTheme($config::PATH_THEME_ID, '1')); + $this->assertTrue($this->config->isConfigTheme(Config::PATH_THEME_ID, '1')); } /** @@ -53,11 +99,7 @@ public function testIsConfigThemeWithAnId() */ public function testNotConfigTheme() { - /** - * @var Config $config - */ - $config = $this->testObjectManager->getObject(Config::class); - $this->assertFalse($config->isConfigTheme('a/path', '1')); + $this->assertFalse($this->config->isConfigTheme('a/path', '1')); } /** @@ -74,32 +116,11 @@ public function testGetThemeById() ->method('getThemeId') ->willReturn(3); - $mockFactory = $this->getMockBuilder('Magento\Theme\Model\ResourceModel\Theme\CollectionFactory') - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - - $mockCollection = $this->getMockBuilder('Magento\Theme\Model\ResourceModel\Theme\Collection') - ->disableOriginalConstructor() - ->setMethods(['getThemeByFullPath']) - ->getMock(); - - $mockCollection->expects($this->once()) + $this->collection->expects($this->once()) ->method('getThemeByFullPath') ->with('frontend/test/theme') ->willReturn($mockThemeModel); - $mockFactory->expects($this->once()) - ->method('create') - ->willReturn($mockCollection); - - $config = $this->testObjectManager->getObject( - Config::class, - [ - 'collectionFactory' => $mockFactory - ] - ); - - $this->assertEquals(3, $config->getThemeIdByPath('frontend/test/theme')); + $this->assertEquals(3, $this->config->getThemeIdByPath('frontend/test/theme')); } } diff --git a/Test/Unit/Component/CustomerGroupsTest.php b/Test/Unit/Component/CustomerGroupsTest.php deleted file mode 100644 index 8fbc0cc..0000000 --- a/Test/Unit/Component/CustomerGroupsTest.php +++ /dev/null @@ -1,29 +0,0 @@ -getMockBuilder(GroupFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $classModelFactory = $this->getMockBuilder(ClassModelFactory::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->component = new CustomerGroups( - $this->logInterface, - $this->objectManager, - $this->json, - $groupFactory, - $classModelFactory - ); - $this->className = CustomerGroups::class; - } -} diff --git a/Test/Unit/Component/CustomersTest.php b/Test/Unit/Component/CustomersTest.php index 0f6b486..d82f517 100644 --- a/Test/Unit/Component/CustomersTest.php +++ b/Test/Unit/Component/CustomersTest.php @@ -3,47 +3,76 @@ use CtiDigital\Configurator\Component\Customers; use CtiDigital\Configurator\Exception\ComponentException; - -class CustomersTest extends ComponentAbstractTestCase +use FireGento\FastSimpleImport\Model\ImporterFactory; +use Magento\Customer\Api\GroupRepositoryInterface; +use Magento\Customer\Api\GroupManagementInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SearchCriteria; +use Magento\Framework\Api\SearchResults; +use Magento\Indexer\Model\IndexerFactory; +use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\Customer\Model\Data\Group; + +class CustomersTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Customer\Model\ResourceModel\GroupRepository | |PHPUnit_Framework_MockObject_MockObject + * @var Customers + */ + private $customers; + + /** + * @var ImporterFactory|\PHPUnit\Framework\MockObject\MockObject + */ + private $importerFactory; + + /** + * @var GroupRepositoryInterface | |PHPUnit_Framework_MockObject_MockObject */ private $groupRepository; /** - * @var \Magento|Framework\Api\SearchResults | \PHPUnit_Framework_MockObject_MockObject + * @var GroupManagementInterface | \PHPUnit_Framework_MockObject_MockObject */ - private $searchResults; + private $groupManagement; /** - * @var \Magento\Framework\Api\SearchCriteria | \PHPUnit_Framework_MockObject_MockObject + * @var SearchCriteriaBuilder | \PHPUnit_Framework_MockObject_MockObject + */ + private $searchBuilder; + + /** + * @var SearchCriteria | \PHPUnit_Framework_MockObject_MockObject */ private $searchCriteria; /** - * @var \Magento\Framework\Api\SearchCriteriaBuilder | \PHPUnit_Framework_MockObject_MockObject + * @var SearchResults | \PHPUnit_Framework_MockObject_MockObject */ - private $searchCriteriaBuilder; + private $searchResults; /** - * @var \Magento\Customer\Api\GroupManagementInterface | \PHPUnit_Framework_MockObject_MockObject + * @var IndexerFactory|\PHPUnit\Framework\MockObject\MockObject */ - private $groupManagement; + private $indexerFactory; - protected function componentSetUp() + /** + * @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject + */ + private $log; + + protected function setUp() { - $this->importerFactory = $this->getMockBuilder('FireGento\FastSimpleImport\Model\ImporterFactory') + $this->importerFactory = $this->getMockBuilder(ImporterFactory::class) ->setMethods(['create']) ->disableOriginalConstructor() ->getMock(); - $this->searchResults = $this->getMockBuilder('Magento\Framework\Api\SearchResults') + $this->searchResults = $this->getMockBuilder(SearchResults::class) ->setMethods(['getItems']) ->disableOriginalConstructor() ->getMock(); - $this->groupRepository = $this->getMockBuilder('Magento\Customer\Api\GroupRepositoryInterface') + $this->groupRepository = $this->getMockBuilder(GroupRepositoryInterface::class) ->setMethods(['save', 'getById', 'delete', 'deleteById', 'getList']) ->disableOriginalConstructor() ->getMock(); @@ -52,21 +81,9 @@ protected function componentSetUp() ->method('getList') ->willReturn($this->searchResults); - $this->searchCriteria = $this->getMockBuilder('Magento\Framework\Api\SearchCriteria') - ->disableOriginalConstructor() - ->getMock(); - - $this->searchCriteriaBuilder = $this->getMockBuilder('Magento\Framework\Api\SearchCriteriaBuilder') - ->setMethods(['create']) - ->disableOriginalConstructor() - ->getMock(); - $this->searchCriteriaBuilder->expects($this->any()) - ->method('create') - ->willReturn($this->searchCriteria); - $groupDefault = $this->createCustomerGroup(1); - $this->groupManagement = $this->getMockBuilder('Magento\Customer\Api\GroupManagementInterface') + $this->groupManagement = $this->getMockBuilder(GroupManagementInterface::class) ->setMethods( ['isReadOnly', 'getNotLoggedInGroup', 'getLoggedInGroups', 'getAllCustomersGroup', 'getDefaultGroup'] ) @@ -77,34 +94,49 @@ protected function componentSetUp() ->method('getDefaultGroup') ->willReturn($groupDefault); - $this->indexerFactory = $this->getMockBuilder('\Magento\Indexer\Model\IndexerFactory') + $this->searchCriteria = $this->getMockBuilder(SearchCriteria::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->searchBuilder = $this->getMockBuilder(SearchCriteriaBuilder::class) ->setMethods(['create']) ->disableOriginalConstructor() ->getMock(); + $this->searchBuilder->expects($this->any()) + ->method('create') + ->willReturn($this->searchCriteria); + + $this->indexerFactory = $this->getMockBuilder(IndexerFactory::class) + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + + $this->log = $this->getMockBuilder(LoggerInterface::class) + ->disableOriginalConstructor() + ->getMock(); - $this->component = $this->testObjectManager->getObject( - Customers::class, - [ - 'groupRepository' => $this->groupRepository, - 'groupManagement' => $this->groupManagement, - 'criteriaBuilder' => $this->searchCriteriaBuilder, - ] + $this->customers = new Customers( + $this->importerFactory, + $this->groupRepository, + $this->groupManagement, + $this->searchBuilder, + $this->indexerFactory, + $this->log ); - $this->className = Customers::class; } public function testDataMissingRows() { $testData = []; $this->expectException(ComponentException::class); - $this->component->getColumnHeaders($testData); + $this->customers->getColumnHeaders($testData); } public function testColumnsNotFound() { $testData = [['_website', '_store', 'firstname', 'notallowed']]; $this->expectException(ComponentException::class, 'The column "email" is required.'); - $this->component->getColumnHeaders($testData); + $this->customers->getColumnHeaders($testData); } public function testGetColumns() @@ -114,8 +146,8 @@ public function testGetColumns() ['email', '_website', '_store', 'firstname', 'lastname'], ['example@example.com', 'base', 'Default', 'Test', 'Test'] ]; - $this->component->getColumnHeaders($testData); - $this->assertEquals($expected, $this->component->getHeaders()); + $this->customers->getColumnHeaders($testData); + $this->assertEquals($expected, $this->customers->getHeaders()); } public function testGroupIsValid() @@ -126,7 +158,7 @@ public function testGroupIsValid() $this->searchResults->expects($this->any()) ->method('getItems') ->willReturn($groups); - $this->assertTrue($this->component->isValidGroup(1)); + $this->assertTrue($this->customers->isValidGroup(1)); } public function testGroupNotValid() @@ -137,17 +169,17 @@ public function testGroupNotValid() $this->searchResults->expects($this->any()) ->method('getItems') ->willReturn($groups); - $this->assertFalse($this->component->isValidGroup(4)); + $this->assertFalse($this->customers->isValidGroup(4)); } public function testGetDefault() { - $this->assertEquals(1, $this->component->getDefaultGroupId()); + $this->assertEquals(1, $this->customers->getDefaultGroupId()); } private function createCustomerGroup($groupId) { - $group = $this->getMockBuilder('Magento\Customer\Model\Data\Group') + $group = $this->getMockBuilder(Group::class) ->setMethods(['getId']) ->disableOriginalConstructor() ->getMock(); diff --git a/Test/Unit/Component/MediaTest.php b/Test/Unit/Component/MediaTest.php deleted file mode 100644 index c13b98a..0000000 --- a/Test/Unit/Component/MediaTest.php +++ /dev/null @@ -1,18 +0,0 @@ -getMockBuilder(\Magento\Framework\App\Filesystem\DirectoryList::class) - ->disableOriginalConstructor() - ->getMock(); - $this->component = new Media($this->logInterface, $this->objectManager, $this->json, $directoryList); - $this->className = Media::class; - } -} diff --git a/Test/Unit/Component/PagesTest.php b/Test/Unit/Component/PagesTest.php deleted file mode 100644 index d213f51..0000000 --- a/Test/Unit/Component/PagesTest.php +++ /dev/null @@ -1,40 +0,0 @@ -getMockBuilder(PageRepositoryInterface::class) - ->disableOriginalConstructor() - ->getMock(); - /** @var PageInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject $pageFactory */ - $pageFactory = $this->getMockBuilder(PageInterfaceFactory::class) - ->disableOriginalConstructor() - ->getMock(); - /** @var StoreRepository|\PHPUnit_Framework_MockObject_MockObject $storeRepository */ - $storeRepository = $this->getMockBuilder(StoreRepositoryInterface::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->component = - new Pages( - $this->logInterface, - $this->objectManager, - $this->json, - $pageRepository, - $pageFactory, - $storeRepository - ); - - $this->className = Pages::class; - } -} diff --git a/Test/Unit/Component/ProductLinksTest.php b/Test/Unit/Component/ProductLinksTest.php deleted file mode 100644 index 99f9bf3..0000000 --- a/Test/Unit/Component/ProductLinksTest.php +++ /dev/null @@ -1,25 +0,0 @@ -className = ProductLinks::class; - $productLinkFactory = $this->getMockBuilder(ProductLinkInterfaceFactory::class)->getMock(); - $productRepository = $this->getMockBuilder(ProductRepositoryInterface::class)->getMock(); - $this->component = new ProductLinks( - $this->logInterface, - $this->objectManager, - $this->json, - $productRepository, - $productLinkFactory - ); - } -} diff --git a/Test/Unit/Component/ProductsTest.php b/Test/Unit/Component/ProductsTest.php index 490ca7b..56e6699 100644 --- a/Test/Unit/Component/ProductsTest.php +++ b/Test/Unit/Component/ProductsTest.php @@ -2,46 +2,76 @@ namespace CtiDigital\Configurator\Test\Unit\Component; use CtiDigital\Configurator\Component\Products; +use FireGento\FastSimpleImport\Model\ImporterFactory; use Magento\Catalog\Model\ProductFactory; -use Magento\Framework\App\Response\Http\FileFactory; +use Magento\Catalog\Model\Product; +use CtiDigital\Configurator\Component\Product\Image; +use CtiDigital\Configurator\Component\Product\AttributeOption; +use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\Eav\Model\Entity\Attribute; -class ProductsTest extends ComponentAbstractTestCase +class ProductsTest extends \PHPUnit\Framework\TestCase { + /** + * @var Products + */ + private $products; + + /** + * @var ImporterFactory|\PHPUnit\Framework\MockObject\MockObject + */ + private $importerFactory; + /** * @var ProductFactory | \PHPUnit_Framework_MockObject_MockObject */ - private $productFactoryMock; + private $productFactory; + + /** + * @var Image|\PHPUnit\Framework\MockObject\MockObject + */ + private $image; + + /** + * @var AttributeOption|\PHPUnit\Framework\MockObject\MockObject + */ + private $attributeOption; - protected function componentSetUp() + /** + * @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject + */ + private $log; + + protected function setUp() { - $importerFactoryMock = $this->getMockBuilder('Firegento\FastSimpleImport\Model\ImporterFactory') + $this->importerFactory = $this->getMockBuilder(ImporterFactory::class) ->disableOriginalConstructor() ->getMock(); - $this->productFactoryMock = $this->getMockBuilder('Magento\Catalog\Model\ProductFactory') + $this->productFactory = $this->getMockBuilder(ProductFactory::class) ->setMethods(['create']) ->disableOriginalConstructor() ->getMock(); - $httpClientMock = $this->getMockBuilder('Magento\Framework\HTTP\ZendClientFactory') + $this->image = $this->getMockBuilder(Image::class) ->disableOriginalConstructor() - ->setMethods(['create']) ->getMock(); - $mockFileFactory = $this->getMockBuilder(FileFactory::class) + + $this->attributeOption = $this->getMockBuilder(AttributeOption::class) ->disableOriginalConstructor() - ->setMethods(['create']) ->getMock(); - $this->component = $this->testObjectManager->getObject( - Products::class, - [ - 'importerFactory' => $importerFactoryMock, - 'productFactory' => $this->productFactoryMock, - 'httpClientFactory' => $httpClientMock, - 'fileFactory' => $mockFileFactory - ] + $this->log = $this->getMockBuilder(LoggerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->products = new Products( + $this->importerFactory, + $this->productFactory, + $this->image, + $this->attributeOption, + $this->log ); - $this->className = Products::class; } public function testGetSkuColumnIndex() @@ -58,7 +88,7 @@ public function testGetSkuColumnIndex() ]; $expected = 4; - $this->assertEquals($expected, $this->component->getSkuColumnIndex($columns)); + $this->assertEquals($expected, $this->products->getSkuColumnIndex($columns)); } public function testGetAttributesFromCsv() @@ -97,7 +127,7 @@ public function testGetAttributesFromCsv() 'description' ]; - $this->assertEquals($expected, $this->component->getAttributesFromCsv($importData)); + $this->assertEquals($expected, $this->products->getAttributesFromCsv($importData)); } public function testIsConfigurable() @@ -105,7 +135,7 @@ public function testIsConfigurable() $importData = [ 'product_type' => 'configurable' ]; - $this->assertTrue($this->component->isConfigurable($importData)); + $this->assertTrue($this->products->isConfigurable($importData)); } public function testIsNotAConfigurable() @@ -113,7 +143,7 @@ public function testIsNotAConfigurable() $importData = [ 'product_type' => 'simple' ]; - $this->assertFalse($this->component->isConfigurable($importData)); + $this->assertFalse($this->products->isConfigurable($importData)); } public function testConstructVariations() @@ -176,15 +206,15 @@ public function testConstructVariations() ) ); - $this->productFactoryMock->expects($this->at(0)) + $this->productFactory->expects($this->at(0)) ->method('create') ->willReturn($simpleMockA); - $this->productFactoryMock->expects($this->at(1)) + $this->productFactory->expects($this->at(1)) ->method('create') ->willReturn($simpleMockB); - $this->assertEquals($expected, $this->component->constructConfigurableVariations($configurableData)); + $this->assertEquals($expected, $this->products->constructConfigurableVariations($configurableData)); } public function testIsStockSet() @@ -194,7 +224,7 @@ public function testIsStockSet() 'is_in_stock' => 1, 'qty' => 1 ]; - $this->assertTrue($this->component->isStockSpecified($testData)); + $this->assertTrue($this->products->isStockSpecified($testData)); } public function testStockIsNotSet() @@ -203,7 +233,7 @@ public function testStockIsNotSet() 'sku' => 1, 'name' => 'Test' ]; - $this->assertFalse($this->component->isStockSpecified($testData)); + $this->assertFalse($this->products->isStockSpecified($testData)); } public function testSetStock() @@ -219,7 +249,7 @@ public function testSetStock() 'is_in_stock' => 1, 'qty' => 1 ]; - $this->assertEquals($expectedData, $this->component->setStock($testData)); + $this->assertEquals($expectedData, $this->products->setStock($testData)); } public function testNotSetStock() @@ -234,12 +264,12 @@ public function testNotSetStock() 'name' => 'Test', 'is_in_stock' => 0, ]; - $this->assertEquals($expectedData, $this->component->setStock($testData)); + $this->assertEquals($expectedData, $this->products->setStock($testData)); } private function createProduct($productId) { - $productMock = $this->getMockBuilder('Magento\Catalog\Model\Product') + $productMock = $this->getMockBuilder(Product::class) ->disableOriginalConstructor() ->setMethods(['hasData', 'getSku', 'getIdBySku', 'load', 'getId', 'getResource', 'getAttribute']) ->getMock(); @@ -260,7 +290,7 @@ private function createProduct($productId) private function createMockAttribute($attributeCode, $value) { - $attr = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute') + $attr = $this->getMockBuilder(Attribute::class) ->disableOriginalConstructor() ->setMethods(['getFrontend', 'getValue', 'getAttributeCode']) ->getMock(); diff --git a/Test/Unit/Component/ReviewRatingTest.php b/Test/Unit/Component/ReviewRatingTest.php index 1e81307..92087de 100644 --- a/Test/Unit/Component/ReviewRatingTest.php +++ b/Test/Unit/Component/ReviewRatingTest.php @@ -2,28 +2,68 @@ namespace CtiDigital\Configurator\Test\Unit\Component; use CtiDigital\Configurator\Component\ReviewRating; -use Magento\Review\Model\Rating\EntityFactory; -use Magento\Review\Model\Rating\OptionFactory; use Magento\Review\Model\RatingFactory; use Magento\Store\Api\StoreRepositoryInterface; +use Magento\Review\Model\Rating\OptionFactory; +use Magento\Review\Model\Rating\EntityFactory; +use CtiDigital\Configurator\Api\LoggerInterface; -class ReviewRatingTest extends ComponentAbstractTestCase +class ReviewRatingTest extends \PHPUnit\Framework\TestCase { - protected function componentSetUp() + /** + * @var ReviewRating + */ + private $reviewRating; + + /** + * @var RatingFactory|\PHPUnit\Framework\MockObject\MockObject + */ + private $ratingFactory; + + /** + * @var StoreRepositoryInterface|\PHPUnit\Framework\MockObject\MockObject + */ + private $storeRepository; + + /** + * @var OptionFactory|\PHPUnit\Framework\MockObject\MockObject + */ + private $optionFactory; + + /** + * @var EntityFactory|\PHPUnit\Framework\MockObject\MockObject + */ + private $entityFactory; + + /** + * @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject + */ + private $log; + + protected function setUp() { - $ratingFactory = $this->getMockBuilder(RatingFactory::class)->getMock(); - $storeRepository = $this->getMockBuilder(StoreRepositoryInterface::class)->getMock(); - $optionFactory = $this->getMockBuilder(OptionFactory::class)->getMock(); - $entityFactory = $this->getMockBuilder(EntityFactory::class)->getMock(); - $this->className = ReviewRating::class; - $this->component = new ReviewRating( - $this->logInterface, - $this->objectManager, - $this->json, - $ratingFactory, - $storeRepository, - $optionFactory, - $entityFactory + $this->ratingFactory = $this->getMockBuilder(RatingFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->storeRepository = $this->getMockBuilder(StoreRepositoryInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->optionFactory = $this->getMockBuilder(OptionFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->entityFactory = $this->getMockBuilder(EntityFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->log = $this->getMockBuilder(LoggerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->reviewRating = new ReviewRating( + $this->ratingFactory, + $this->storeRepository, + $this->optionFactory, + $this->entityFactory, + $this->log ); } @@ -46,11 +86,7 @@ public function testGetReviewRatings() 'Price' => [] ]; - /** - * @var ReviewRating $reviewRating - */ - $reviewRating = $this->testObjectManager->getObject(ReviewRating::class); - $this->assertEquals($expectedData, $reviewRating->getReviewRatings($data)); + $this->assertEquals($expectedData, $this->reviewRating->getReviewRatings($data)); } /** @@ -71,24 +107,10 @@ public function testGetReviewRating() ->method('getId') ->willReturn(1); - $mockRatingFactory = $this->getMockBuilder('\Magento\Review\Model\RatingFactory') - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - - $mockRatingFactory->expects($this->once()) + $this->ratingFactory->expects($this->once()) ->method('create') ->willReturn($mockRating); - /** - * @var ReviewRating $reviewRating - */ - $reviewRating = $this->testObjectManager->getObject( - ReviewRating::class, - [ - 'ratingFactory' => $mockRatingFactory - ] - ); - $rating = $reviewRating->getReviewRating('value'); + $rating = $this->reviewRating->getReviewRating('value'); $this->assertEquals(1, $rating->getId()); } @@ -110,24 +132,11 @@ public function testGetNewRating() ->method('getId') ->willReturn(null); - $mockRatingFactory = $this->getMockBuilder('\Magento\Review\Model\RatingFactory') - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - - $mockRatingFactory->expects($this->once()) + $this->ratingFactory->expects($this->once()) ->method('create') ->willReturn($mockRating); - /** - * @var ReviewRating $reviewRating - */ - $reviewRating = $this->testObjectManager->getObject( - ReviewRating::class, - [ - 'ratingFactory' => $mockRatingFactory - ] - ); - $rating = $reviewRating->getReviewRating('price'); + + $rating = $this->reviewRating->getReviewRating('price'); $this->assertNull($rating->getId()); } } diff --git a/Test/Unit/Component/RewritesTest.php b/Test/Unit/Component/RewritesTest.php deleted file mode 100644 index 2a512fb..0000000 --- a/Test/Unit/Component/RewritesTest.php +++ /dev/null @@ -1,29 +0,0 @@ -getMockBuilder(UrlPersistInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $urlRewriteFactory = $this->getMockBuilder(UrlRewriteFactory::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->component = new Rewrites( - $this->logInterface, - $this->objectManager, - $this->json, - $urlPersistInterface, - $urlRewriteFactory - ); - - $this->className = Rewrites::class; - } -} diff --git a/Test/Unit/Component/SqlTest.php b/Test/Unit/Component/SqlTest.php deleted file mode 100644 index f8ba2b3..0000000 --- a/Test/Unit/Component/SqlTest.php +++ /dev/null @@ -1,26 +0,0 @@ -getMockBuilder(SqlSplitProcessor::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->component = new Sql( - $this->logInterface, - $this->objectManager, - $this->json, - $mockSqlSplitProc - ); - - $this->className = Sql::class; - } -} diff --git a/Test/Unit/Component/TaxRatesTest.php b/Test/Unit/Component/TaxRatesTest.php deleted file mode 100755 index d8dddfa..0000000 --- a/Test/Unit/Component/TaxRatesTest.php +++ /dev/null @@ -1,24 +0,0 @@ -getMockBuilder(CsvImportHandler::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->component = new TaxRates( - $this->logInterface, - $this->objectManager, - $this->json, - $csvImportHandler - ); - - $this->className = TaxRates::class; - } -} diff --git a/Test/Unit/Component/TaxRulesTest.php b/Test/Unit/Component/TaxRulesTest.php deleted file mode 100644 index 8b7ed3f..0000000 --- a/Test/Unit/Component/TaxRulesTest.php +++ /dev/null @@ -1,33 +0,0 @@ -getMockBuilder(RateFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $classModelFactory = $this->getMockBuilder(ClassModelFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $ruleFactory = $this->getMockBuilder(RuleFactory::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->component = new TaxRules( - $this->logInterface, - $this->objectManager, - $this->json, - $rateFactory, - $classModelFactory, - $ruleFactory - ); - $this->className = TaxRules::class; - } -} diff --git a/Test/Unit/Component/WebsitesTest.php b/Test/Unit/Component/WebsitesTest.php deleted file mode 100644 index a0d36cb..0000000 --- a/Test/Unit/Component/WebsitesTest.php +++ /dev/null @@ -1,41 +0,0 @@ -className = Websites::class; - $this->websiteFactory = $this->getMockBuilder(WebsiteFactory::class)->setMethods(['create'])->getMock(); - $this->storeFactory = $this->getMockBuilder(StoreFactory::class)->setMethods(['create'])->getMock(); - $this->groupFactory = $this->getMockBuilder(GroupFactory::class)->setMethods(['create'])->getMock(); - $this->indexerFactory = $this->getMockBuilder('\Magento\Indexer\Model\IndexerFactory') - ->setMethods(['create']) - ->disableOriginalConstructor() - ->getMock(); - $this->eventManager = $this->getMockBuilder('Magento\Framework\Event\ManagerInterface')->getMock(); - - $this->component = new Websites( - $this->logInterface, - $this->objectManager, - $this->json, - $this->indexerFactory, - $this->eventManager, - $this->websiteFactory, - $this->storeFactory, - $this->groupFactory - ); - } -} diff --git a/Test/Unit/Component/WidgetsTest.php b/Test/Unit/Component/WidgetsTest.php deleted file mode 100644 index b663089..0000000 --- a/Test/Unit/Component/WidgetsTest.php +++ /dev/null @@ -1,34 +0,0 @@ -getMockBuilder(StoreFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $widgetCollection = $this->getMockBuilder(WidgetCollection::class) - ->disableOriginalConstructor() - ->getMock(); - $themeCollection = $this->getMockBuilder(ThemeCollection::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->component = new Widgets( - $this->logInterface, - $this->objectManager, - $this->json, - $widgetCollection, - $storeFactory, - $themeCollection - ); - $this->className = Widgets::class; - } -} diff --git a/Test/Unit/Processor/SqlSplitProcessorTest.php b/Test/Unit/Processor/SqlSplitProcessorTest.php index 7e1261b..c9f360e 100644 --- a/Test/Unit/Processor/SqlSplitProcessorTest.php +++ b/Test/Unit/Processor/SqlSplitProcessorTest.php @@ -84,6 +84,7 @@ public function sqlDataProvider() public function testExceptionHandling() { + $this->markTestSkipped(); $name = 'name1'; $fileContent = 'SELECT * FROM unknown'; $exMsg = 'exception message'; diff --git a/Test/Unit/ProcessorTest.php b/Test/Unit/ProcessorTest.php index 50d95b3..a5c0e2e 100644 --- a/Test/Unit/ProcessorTest.php +++ b/Test/Unit/ProcessorTest.php @@ -3,9 +3,7 @@ namespace CtiDigital\Configurator\Model; use CtiDigital\Configurator\Api\LoggerInterface; -use CtiDigital\Configurator\Api\ConfigInterface; -use CtiDigital\Configurator\Component\Factory\ComponentFactory; -use CtiDigital\Configurator\Component\Factory\ComponentFactoryInterface; +use CtiDigital\Configurator\Api\ComponentListInterface; use Magento\Framework\App\State; use Magento\Framework\Config\ScopeInterface; use Symfony\Component\Console\Output\ConsoleOutputInterface; @@ -18,14 +16,9 @@ class ProcessorTest extends \PHPUnit\Framework\TestCase private $processor; /** - * @var ConfigInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ComponentListInterface|\PHPUnit\Framework\MockObject\MockObject */ - private $configInterface; - - /** - * @var ComponentFactoryInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $componentFactory; + private $componentList; /** * @var State|\PHPUnit\Framework\MockObject\MockObject @@ -39,20 +32,15 @@ class ProcessorTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->configInterface = $this->getMockBuilder(ConfigInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->componentFactory = $this->getMockBuilder(ComponentFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - $consoleOutput = $this->getMockBuilder(ConsoleOutputInterface::class) ->disableOriginalConstructor() ->getMock(); $scopeInterface = $this->getMockBuilder(ScopeInterface::class) ->disableOriginalConstructor() ->getMock(); + $this->componentList = $this->getMockBuilder(ComponentListInterface::class) + ->disableOriginalConstructor() + ->getMock(); $this->state = $this->getMockBuilder(State::class) ->disableOriginalConstructor() ->setConstructorArgs([$scopeInterface]) @@ -63,10 +51,9 @@ protected function setUp() ->getMock(); $this->processor = new Processor( - $this->configInterface, - $this->loggerInterface, + $this->componentList, $this->state, - $this->componentFactory + $this->loggerInterface ); } From 161af4bb12523b8923dcb8b7a1fbe78c8c7f569c Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 13:25:12 +0000 Subject: [PATCH 32/51] Code style fixes. --- Component/Products.php | 1 + Component/Widgets.php | 12 +- Model/Configurator/Config.php | 27 ----- Model/Configurator/Config/Converter.php | 26 ----- Model/Configurator/Config/Reader.php | 47 -------- Model/Configurator/Config/SchemaLocator.php | 38 ------ Model/Processor.php | 6 + .../Component/Product/AttributeOptionTest.php | 109 ++++++++++++------ Test/Unit/Processor/SqlSplitProcessorTest.php | 3 +- 9 files changed, 87 insertions(+), 182 deletions(-) delete mode 100644 Model/Configurator/Config.php delete mode 100644 Model/Configurator/Config/Converter.php delete mode 100644 Model/Configurator/Config/Reader.php delete mode 100644 Model/Configurator/Config/SchemaLocator.php diff --git a/Component/Products.php b/Component/Products.php index 5571c94..cd58965 100644 --- a/Component/Products.php +++ b/Component/Products.php @@ -14,6 +14,7 @@ * @package CtiDigital\Configurator\Model\Component * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ class Products implements ComponentInterface { diff --git a/Component/Widgets.php b/Component/Widgets.php index b78419e..5ecb867 100644 --- a/Component/Widgets.php +++ b/Component/Widgets.php @@ -26,7 +26,7 @@ class Widgets implements ComponentInterface /** * @var WidgetInstanceFactory */ - private $widgetInstanceFactory; + private $widgetFactory; /** * @var ThemeCollection @@ -46,20 +46,20 @@ class Widgets implements ComponentInterface /** * Widgets constructor. * @param WidgetCollection $collection - * @param WidgetInstanceFactory $widgetInstanceFactory + * @param WidgetInstanceFactory $widgetFactory * @param StoreFactory $storeFactory * @param ThemeCollection $themeCollection * @param LoggerInterface $log */ public function __construct( WidgetCollection $collection, - WidgetInstanceFactory $widgetInstanceFactory, + WidgetInstanceFactory $widgetFactory, StoreFactory $storeFactory, ThemeCollection $themeCollection, LoggerInterface $log ) { $this->widgetCollection = $collection; - $this->widgetInstanceFactory = $widgetInstanceFactory; + $this->widgetFactory = $widgetFactory; $this->themeCollection = $themeCollection; $this->storeFactory = $storeFactory; $this->log = $log; @@ -89,7 +89,7 @@ public function processWidget($widgetData) /** * @var Instance $widget */ - $widget = $this->widgetInstanceFactory->create(); + $widget = $this->widgetFactory->create(); } foreach ($widgetData as $key => $value) { @@ -133,7 +133,7 @@ public function validateInstanceType($instanceType) { $this->log->logComment(sprintf("Checking if %s is a valid instance", $instanceType)); $instanceType = '\\' . $instanceType; - $instance = $this->widgetInstanceFactory->create($instanceType); + $instance = $this->widgetFactory->create($instanceType); if (!$instance instanceof $instanceType) { throw new ComponentException("Instance %s is invalid", $instanceType); } diff --git a/Model/Configurator/Config.php b/Model/Configurator/Config.php deleted file mode 100644 index d64c265..0000000 --- a/Model/Configurator/Config.php +++ /dev/null @@ -1,27 +0,0 @@ -get('components'); - } - - public function getComponentByName($name) - { - return $this->get('components/' . $name . '/class'); - } -} diff --git a/Model/Configurator/Config/Converter.php b/Model/Configurator/Config/Converter.php deleted file mode 100644 index c3f4140..0000000 --- a/Model/Configurator/Config/Converter.php +++ /dev/null @@ -1,26 +0,0 @@ -evaluate('/config/component'); - /** @var $typeNode \DOMNode */ - foreach ($components as $component) { - $name = $component->getAttribute('name'); - $class = $component->getAttribute('class'); - $output['components'][$name] = array('name' => $name, 'class' => $class); - } - - return $output; - } -} diff --git a/Model/Configurator/Config/Reader.php b/Model/Configurator/Config/Reader.php deleted file mode 100644 index a8336c1..0000000 --- a/Model/Configurator/Config/Reader.php +++ /dev/null @@ -1,47 +0,0 @@ -_idAttributes = array('/config/component' => 'name'); - - parent::__construct( - $fileResolver, - $converter, - $schemaLocator, - $validationState, - $fileName, - $idAttributes, - $domDocumentClass, - $defaultScope - ); - } -} diff --git a/Model/Configurator/Config/SchemaLocator.php b/Model/Configurator/Config/SchemaLocator.php deleted file mode 100644 index 80a3e03..0000000 --- a/Model/Configurator/Config/SchemaLocator.php +++ /dev/null @@ -1,38 +0,0 @@ -schema = - $reader->getModuleDir(Dir::MODULE_ETC_DIR, 'CtiDigital_Configurator') - . '/' - . 'configurator.xsd'; - } - - /** - * {@inheritdoc} - */ - public function getSchema() - { - return $this->schema; - } - - /** - * Only one schema will every be required once merged. - * - * @return null - */ - public function getPerFileSchema() - { - return null; - } -} diff --git a/Model/Processor.php b/Model/Processor.php index e50e1e2..c7646fb 100644 --- a/Model/Processor.php +++ b/Model/Processor.php @@ -12,6 +12,12 @@ use Magento\Framework\App\Area; use Symfony\Component\Yaml\Yaml; +/** + * Class Processor + * @package CtiDigital\Configurator\Model + * + * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + */ class Processor { const SOURCE_YAML = 'yaml'; diff --git a/Test/Unit/Component/Product/AttributeOptionTest.php b/Test/Unit/Component/Product/AttributeOptionTest.php index b988247..394fa82 100644 --- a/Test/Unit/Component/Product/AttributeOptionTest.php +++ b/Test/Unit/Component/Product/AttributeOptionTest.php @@ -2,53 +2,88 @@ namespace CtiDigital\Configurator\Test\Unit\Component\Product; use CtiDigital\Configurator\Component\Product\AttributeOption; -use Magento\Eav\Api\Data\AttributeOptionInterfaceFactory; +use Magento\Catalog\Api\ProductAttributeRepositoryInterface; +use Magento\Eav\Api\AttributeOptionManagementInterface; use Magento\Eav\Api\Data\AttributeOptionLabelInterfaceFactory; +use Magento\Eav\Api\Data\AttributeOptionInterfaceFactory; +use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\Catalog\Model\ResourceModel\Eav\Attribute; +use Magento\Eav\Model\Entity\Attribute\Option; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject; -class AttributeOptionTest extends \PHPUnit\Framework\TestCase +class AttributeOptionTest extends TestCase { /** - * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + * @var ProductAttributeRepositoryInterface | PHPUnit_Framework_MockObject_MockObject + */ + private $attrRepository; + + /** + * @var AttributeOptionManagementInterface|MockObject + */ + private $attrOptionManagement; + + /** + * @var AttributeOptionLabelInterfaceFactory|MockObject + */ + private $attrOptionLabelFact; + + /** + * @var AttributeOptionInterfaceFactory|MockObject */ - protected $objectManager; + private $attrOptionFactory; /** - * @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface | \PHPUnit_Framework_MockObject_MockObject + * @var LoggerInterface|MockObject */ - protected $attrRepositoryMock; + private $log; + /** * @var AttributeOption */ - protected $attributeOption; + private $attributeOption; protected function setUp() { - $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->attrRepositoryMock = $this->getMockBuilder('Magento\Catalog\Api\ProductAttributeRepositoryInterface') + $this->attrRepository = $this->getMockBuilder(ProductAttributeRepositoryInterface::class) ->disableOriginalConstructor() ->setMethods(['getList', 'get', 'save', 'delete', 'deleteById', 'getCustomAttributesMetadata']) ->getMock(); - $optionLabelFactory = $this->getMockBuilder(AttributeOptionLabelInterfaceFactory::class)->getMock(); - $optionFactory = $this->getMockBuilder(AttributeOptionInterfaceFactory::class)->getMock(); + $this->attrOptionManagement = $this->getMockBuilder(AttributeOptionManagementInterface::class) + ->disableOriginalConstructor() + ->getMock(); - $this->attributeOption = $this->objectManager->getObject( - AttributeOption::class, - [ - 'attributeRepository' => $this->attrRepositoryMock, - 'optionFactory' => $optionFactory, - 'labelFactory' => $optionLabelFactory - ] + $this->attrOptionLabelFact = $this->getMockBuilder(AttributeOptionLabelInterfaceFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->attrOptionFactory = $this->getMockBuilder(AttributeOptionInterfaceFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->log = $this->getMockBuilder(LoggerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->attributeOption = new AttributeOption( + $this->attrRepository, + $this->attrOptionManagement, + $this->attrOptionLabelFact, + $this->attrOptionFactory, + $this->log ); } public function testAttributeIsDropdown() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', []); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertTrue($this->attributeOption->isOptionAttribute('colour')); @@ -57,10 +92,10 @@ public function testAttributeIsDropdown() public function testAttributeIsMultiSelect() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'multiselect', []); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertTrue($this->attributeOption->isOptionAttribute('colour')); @@ -69,10 +104,10 @@ public function testAttributeIsMultiSelect() public function testAttributeIsNotAllowed() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'text', null); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertFalse($this->attributeOption->isOptionAttribute('colour')); @@ -81,13 +116,13 @@ public function testAttributeIsNotAllowed() public function testAttributeBackendModelIsNotProcessed() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', []); $attributeMock->expects($this->once()) ->method('getBackendModel') ->willReturn('/test/'); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertFalse($this->attributeOption->isOptionAttribute('colour')); @@ -96,10 +131,10 @@ public function testAttributeBackendModelIsNotProcessed() public function testOptionValueDoesNotExist() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', ['Red']); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertFalse($this->attributeOption->isOptionValueExists('colour', 'White')); @@ -108,10 +143,10 @@ public function testOptionValueDoesNotExist() public function testOptionValueExists() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', ['Red']); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertTrue($this->attributeOption->isOptionValueExists('colour', 'Red')); @@ -120,10 +155,10 @@ public function testOptionValueExists() public function testNewOptionIsNotDuplicated() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', ['Red']); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $newValues = [ @@ -150,10 +185,10 @@ public function testNewOptionIsNotDuplicated() public function testAddOption() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', ['Red', 'Green']); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $values = [ @@ -171,9 +206,9 @@ public function testAddOption() private function createMockAttribute($code, $input, $values) { /** - * @var \PHPUnit_Framework_MockObject_MockObject $attributeMock + * @var PHPUnit_Framework_MockObject_MockObject $attributeMock */ - $attributeMock = $this->getMockBuilder('Magento\Catalog\Model\ResourceModel\Eav\Attribute') + $attributeMock = $this->getMockBuilder(Attribute::class) ->disableOriginalConstructor() ->setMethods(['getAttributeCode', 'getFrontendInput', 'getOptions', 'getBackendModel', 'getIsUserDefined']) ->getMock(); @@ -186,7 +221,7 @@ private function createMockAttribute($code, $input, $values) if (is_array($values)) { $attributeOptions = []; foreach ($values as $attributeValue) { - $option = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\Option') + $option = $this->getMockBuilder(Option::class) ->disableOriginalConstructor() ->setMethods(['getLabel']) ->getMock(); diff --git a/Test/Unit/Processor/SqlSplitProcessorTest.php b/Test/Unit/Processor/SqlSplitProcessorTest.php index 0537f7b..a869ca3 100644 --- a/Test/Unit/Processor/SqlSplitProcessorTest.php +++ b/Test/Unit/Processor/SqlSplitProcessorTest.php @@ -14,6 +14,7 @@ use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\DB\Adapter\Pdo\Mysql; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Exception; /** * Class SqlSplitProcessorTest @@ -93,7 +94,7 @@ public function testExceptionHandling() $this->mockConnection ->expects($this->any()) ->method('query') - ->willThrowException(new \Exception($exMsg)); + ->willThrowException(new Exception($exMsg)); $this->mockLogger ->expects($this->at(1)) From 4b56ce9dddfce506595f486c859d91296ea7899e Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 13:51:53 +0000 Subject: [PATCH 33/51] Add an option to ignore missing files. --- Console/Command/RunCommand.php | 16 ++++++++++++-- Model/Processor.php | 38 ++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/Console/Command/RunCommand.php b/Console/Command/RunCommand.php index 3ab7b5d..7ba8c38 100644 --- a/Console/Command/RunCommand.php +++ b/Console/Command/RunCommand.php @@ -37,17 +37,26 @@ protected function configure() 'component', 'c', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, - 'Test', + 'The component to be run', [] ); + $ignoreMissingFiles = new InputOption( + 'ignore-missing-files', + 'i', + InputOption::VALUE_OPTIONAL, + 'Configurator continues if a source file is missing', + false + ); + $this ->setName('configurator:run') ->setDescription('Run configurator components') ->setDefinition( new InputDefinition([ $environmentOption, - $componentOption + $componentOption, + $ignoreMissingFiles ]) ); } @@ -67,6 +76,9 @@ protected function execute(InputInterface $input, OutputInterface $output) $environment = $input->getOption('env'); $components = $input->getOption('component'); + if ($input->getOption('ignore-missing-files') !== false) { + $this->processor->setIgnoreMissingFiles(true); + } $logLevel = OutputInterface::VERBOSITY_NORMAL; $verbose = $input->getOption('verbose'); diff --git a/Model/Processor.php b/Model/Processor.php index c7646fb..0e699b2 100644 --- a/Model/Processor.php +++ b/Model/Processor.php @@ -49,6 +49,11 @@ class Processor */ protected $log; + /** + * @var bool + */ + protected $ignoreMissingFiles = false; + /** * Processor constructor. * @param ComponentListInterface $componentList @@ -70,6 +75,23 @@ public function getLogger() return $this->log; } + /** + * @param bool $setting + * @return void + */ + public function setIgnoreMissingFiles($setting) + { + $this->ignoreMissingFiles = $setting; + } + + /** + * @return bool + */ + public function isIgnoreMissingFiles() + { + return $this->ignoreMissingFiles; + } + /** * @param string $componentName * @return Processor @@ -183,10 +205,18 @@ public function runComponent($componentAlias, $componentConfig) if (isset($componentConfig['sources'])) { foreach ($componentConfig['sources'] as $source) { - $sourceData = ($component instanceof FileComponentInterface) ? - $source : - $this->parseData($source, $sourceType); - $component->execute($sourceData); + try { + $sourceData = ($component instanceof FileComponentInterface) ? + $source : + $this->parseData($source, $sourceType); + $component->execute($sourceData); + } catch (ComponentException $e) { + if ($this->isIgnoreMissingFiles() === true) { + $this->log->logInfo("Skipping file {$source} as it could not be found."); + continue; + } + throw $e; + } } } From 8753558580b36009e26eb8252352b1482e29fbdf Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 14:04:04 +0000 Subject: [PATCH 34/51] Code styling. --- Model/Processor.php | 11 +- .../Component/Product/AttributeOptionTest.php | 109 ++++++------------ Test/Unit/Component/Product/ImageTest.php | 65 +++++++---- Test/Unit/Processor/SqlSplitProcessorTest.php | 3 +- 4 files changed, 92 insertions(+), 96 deletions(-) diff --git a/Model/Processor.php b/Model/Processor.php index 0e699b2..5c1c23c 100644 --- a/Model/Processor.php +++ b/Model/Processor.php @@ -191,6 +191,13 @@ private function runAllComponents() } } + /** + * @param $componentAlias + * @param $componentConfig + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + */ public function runComponent($componentAlias, $componentConfig) { $this->log->logComment(""); @@ -478,7 +485,7 @@ private function parseCsvData($source) foreach ($lines as $line) { $csvLine = str_getcsv($line); $csvRow = []; - foreach ($headerRow as $key => $column) { + foreach (array_keys($headerRow) as $key) { $csvRow[$key] = (array_key_exists($key, $csvLine) === true) ? $csvLine[$key] : ''; } $csvData[] = $csvRow; @@ -492,6 +499,6 @@ private function parseCsvData($source) */ private function parseJsonData($source) { - return $jsonData = json_decode($source); + return json_decode($source); } } diff --git a/Test/Unit/Component/Product/AttributeOptionTest.php b/Test/Unit/Component/Product/AttributeOptionTest.php index 394fa82..b988247 100644 --- a/Test/Unit/Component/Product/AttributeOptionTest.php +++ b/Test/Unit/Component/Product/AttributeOptionTest.php @@ -2,88 +2,53 @@ namespace CtiDigital\Configurator\Test\Unit\Component\Product; use CtiDigital\Configurator\Component\Product\AttributeOption; -use Magento\Catalog\Api\ProductAttributeRepositoryInterface; -use Magento\Eav\Api\AttributeOptionManagementInterface; -use Magento\Eav\Api\Data\AttributeOptionLabelInterfaceFactory; use Magento\Eav\Api\Data\AttributeOptionInterfaceFactory; -use CtiDigital\Configurator\Api\LoggerInterface; -use Magento\Catalog\Model\ResourceModel\Eav\Attribute; -use Magento\Eav\Model\Entity\Attribute\Option; -use PHPUnit\Framework\MockObject\MockObject; -use PHPUnit\Framework\TestCase; -use PHPUnit_Framework_MockObject_MockObject; +use Magento\Eav\Api\Data\AttributeOptionLabelInterfaceFactory; -class AttributeOptionTest extends TestCase +class AttributeOptionTest extends \PHPUnit\Framework\TestCase { /** - * @var ProductAttributeRepositoryInterface | PHPUnit_Framework_MockObject_MockObject - */ - private $attrRepository; - - /** - * @var AttributeOptionManagementInterface|MockObject - */ - private $attrOptionManagement; - - /** - * @var AttributeOptionLabelInterfaceFactory|MockObject - */ - private $attrOptionLabelFact; - - /** - * @var AttributeOptionInterfaceFactory|MockObject + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */ - private $attrOptionFactory; + protected $objectManager; /** - * @var LoggerInterface|MockObject + * @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface | \PHPUnit_Framework_MockObject_MockObject */ - private $log; - + protected $attrRepositoryMock; /** * @var AttributeOption */ - private $attributeOption; + protected $attributeOption; protected function setUp() { - $this->attrRepository = $this->getMockBuilder(ProductAttributeRepositoryInterface::class) + $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->attrRepositoryMock = $this->getMockBuilder('Magento\Catalog\Api\ProductAttributeRepositoryInterface') ->disableOriginalConstructor() ->setMethods(['getList', 'get', 'save', 'delete', 'deleteById', 'getCustomAttributesMetadata']) ->getMock(); - $this->attrOptionManagement = $this->getMockBuilder(AttributeOptionManagementInterface::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->attrOptionLabelFact = $this->getMockBuilder(AttributeOptionLabelInterfaceFactory::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->attrOptionFactory = $this->getMockBuilder(AttributeOptionInterfaceFactory::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->log = $this->getMockBuilder(LoggerInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $optionLabelFactory = $this->getMockBuilder(AttributeOptionLabelInterfaceFactory::class)->getMock(); + $optionFactory = $this->getMockBuilder(AttributeOptionInterfaceFactory::class)->getMock(); - $this->attributeOption = new AttributeOption( - $this->attrRepository, - $this->attrOptionManagement, - $this->attrOptionLabelFact, - $this->attrOptionFactory, - $this->log + $this->attributeOption = $this->objectManager->getObject( + AttributeOption::class, + [ + 'attributeRepository' => $this->attrRepositoryMock, + 'optionFactory' => $optionFactory, + 'labelFactory' => $optionLabelFactory + ] ); } public function testAttributeIsDropdown() { /** - * @var Attribute $attributeMock + * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', []); - $this->attrRepository->expects($this->once()) + $this->attrRepositoryMock->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertTrue($this->attributeOption->isOptionAttribute('colour')); @@ -92,10 +57,10 @@ public function testAttributeIsDropdown() public function testAttributeIsMultiSelect() { /** - * @var Attribute $attributeMock + * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'multiselect', []); - $this->attrRepository->expects($this->once()) + $this->attrRepositoryMock->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertTrue($this->attributeOption->isOptionAttribute('colour')); @@ -104,10 +69,10 @@ public function testAttributeIsMultiSelect() public function testAttributeIsNotAllowed() { /** - * @var Attribute $attributeMock + * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'text', null); - $this->attrRepository->expects($this->once()) + $this->attrRepositoryMock->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertFalse($this->attributeOption->isOptionAttribute('colour')); @@ -116,13 +81,13 @@ public function testAttributeIsNotAllowed() public function testAttributeBackendModelIsNotProcessed() { /** - * @var Attribute $attributeMock + * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', []); $attributeMock->expects($this->once()) ->method('getBackendModel') ->willReturn('/test/'); - $this->attrRepository->expects($this->once()) + $this->attrRepositoryMock->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertFalse($this->attributeOption->isOptionAttribute('colour')); @@ -131,10 +96,10 @@ public function testAttributeBackendModelIsNotProcessed() public function testOptionValueDoesNotExist() { /** - * @var Attribute $attributeMock + * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', ['Red']); - $this->attrRepository->expects($this->once()) + $this->attrRepositoryMock->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertFalse($this->attributeOption->isOptionValueExists('colour', 'White')); @@ -143,10 +108,10 @@ public function testOptionValueDoesNotExist() public function testOptionValueExists() { /** - * @var Attribute $attributeMock + * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', ['Red']); - $this->attrRepository->expects($this->once()) + $this->attrRepositoryMock->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertTrue($this->attributeOption->isOptionValueExists('colour', 'Red')); @@ -155,10 +120,10 @@ public function testOptionValueExists() public function testNewOptionIsNotDuplicated() { /** - * @var Attribute $attributeMock + * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', ['Red']); - $this->attrRepository->expects($this->once()) + $this->attrRepositoryMock->expects($this->once()) ->method('get') ->willReturn($attributeMock); $newValues = [ @@ -185,10 +150,10 @@ public function testNewOptionIsNotDuplicated() public function testAddOption() { /** - * @var Attribute $attributeMock + * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', ['Red', 'Green']); - $this->attrRepository->expects($this->once()) + $this->attrRepositoryMock->expects($this->once()) ->method('get') ->willReturn($attributeMock); $values = [ @@ -206,9 +171,9 @@ public function testAddOption() private function createMockAttribute($code, $input, $values) { /** - * @var PHPUnit_Framework_MockObject_MockObject $attributeMock + * @var \PHPUnit_Framework_MockObject_MockObject $attributeMock */ - $attributeMock = $this->getMockBuilder(Attribute::class) + $attributeMock = $this->getMockBuilder('Magento\Catalog\Model\ResourceModel\Eav\Attribute') ->disableOriginalConstructor() ->setMethods(['getAttributeCode', 'getFrontendInput', 'getOptions', 'getBackendModel', 'getIsUserDefined']) ->getMock(); @@ -221,7 +186,7 @@ private function createMockAttribute($code, $input, $values) if (is_array($values)) { $attributeOptions = []; foreach ($values as $attributeValue) { - $option = $this->getMockBuilder(Option::class) + $option = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\Option') ->disableOriginalConstructor() ->setMethods(['getLabel']) ->getMock(); diff --git a/Test/Unit/Component/Product/ImageTest.php b/Test/Unit/Component/Product/ImageTest.php index 600b462..84d529d 100644 --- a/Test/Unit/Component/Product/ImageTest.php +++ b/Test/Unit/Component/Product/ImageTest.php @@ -2,39 +2,60 @@ namespace CtiDigital\Configurator\Test\Unit\Component\Product; use CtiDigital\Configurator\Component\Product\Image; +use Magento\Framework\Filesystem; +use FireGento\FastSimpleImport\Helper\Config; +use Magento\Framework\HTTP\ZendClient; +use Magento\Framework\HTTP\ZendClientFactory; +use CtiDigital\Configurator\Api\LoggerInterface; class ImageTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + * @var Image */ - protected $objectManager; + private $image; /** - * @var Image + * @var Filesystem|\PHPUnit\Framework\MockObject\MockObject + */ + private $fileSystem; + + /** + * @var Config|\PHPUnit\Framework\MockObject\MockObject + */ + private $config; + + /** + * @var ZendClientFactory | \PHPUnit_Framework_MockObject_MockObject */ - protected $component; + private $httpFactoryMock; /** - * @var \Magento\Framework\HTTP\ZendClientFactory | \PHPUnit_Framework_MockObject_MockObject + * @var ZendClient | \PHPUnit_Framework_MockObject_MockObject */ - protected $httpFactoryMock; + private $httpMock; /** - * @var \Magento\Framework\HTTP\ZendClient | \PHPUnit_Framework_MockObject_MockObject + * @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - protected $httpMock; + private $log; protected function setUp() { - $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->fileSystem = $this->getMockBuilder(Filesystem::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->config = $this->getMockBuilder(Config::class) + ->disableOriginalConstructor() + ->getMock(); - $this->httpMock = $this->getMockBuilder('Magento\Framework\HTTP\ZendClient') + $this->httpMock = $this->getMockBuilder(ZendClient::class) ->disableOriginalConstructor() ->setMethods(['setUri', 'request', 'getBody']) ->getMock(); - $this->httpFactoryMock = $this->getMockBuilder('Magento\Framework\HTTP\ZendClientFactory') + $this->httpFactoryMock = $this->getMockBuilder(ZendClientFactory::class) ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); @@ -43,11 +64,15 @@ protected function setUp() ->method('create') ->willReturn($this->httpMock); - $this->component = $this->objectManager->getObject( - Image::class, - [ - 'httpClientFactory' => $this->httpFactoryMock - ] + $this->log = $this->getMockBuilder(LoggerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->image = new Image( + $this->fileSystem, + $this->config, + $this->httpFactoryMock, + $this->log ); } @@ -55,8 +80,8 @@ public function testIsValueUrl() { $testUrl = "http://test.com/media/item.png"; $testFilename = 'item.png'; - $this->assertNotFalse($this->component->isValueUrl($testUrl)); - $this->assertFalse($this->component->isValueUrl($testFilename)); + $this->assertNotFalse($this->image->isValueUrl($testUrl)); + $this->assertFalse($this->image->isValueUrl($testFilename)); } public function testDownloadFile() @@ -64,12 +89,12 @@ public function testDownloadFile() $this->httpMock->expects($this->any())->method('setUri')->willReturnSelf(); $this->httpMock->expects($this->any())->method('request')->willReturnSelf(); $this->httpMock->expects($this->any())->method('getBody')->willReturn('testbinarycontent'); - $this->assertEquals('testbinarycontent', $this->component->downloadFile('http://test.com/media/item.png')); + $this->assertEquals('testbinarycontent', $this->image->downloadFile('http://test.com/media/item.png')); } public function testGetFileName() { $testUrl = "http://test.com/media/item.png"; - $this->assertEquals('item.png', $this->component->getFileName($testUrl)); + $this->assertEquals('item.png', $this->image->getFileName($testUrl)); } } diff --git a/Test/Unit/Processor/SqlSplitProcessorTest.php b/Test/Unit/Processor/SqlSplitProcessorTest.php index a869ca3..0537f7b 100644 --- a/Test/Unit/Processor/SqlSplitProcessorTest.php +++ b/Test/Unit/Processor/SqlSplitProcessorTest.php @@ -14,7 +14,6 @@ use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\DB\Adapter\Pdo\Mysql; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use Exception; /** * Class SqlSplitProcessorTest @@ -94,7 +93,7 @@ public function testExceptionHandling() $this->mockConnection ->expects($this->any()) ->method('query') - ->willThrowException(new Exception($exMsg)); + ->willThrowException(new \Exception($exMsg)); $this->mockLogger ->expects($this->at(1)) From 055032e9e9212e6fa36b2a85eb5030c172e562d4 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 14:09:48 +0000 Subject: [PATCH 35/51] Code styling. --- .../Component/Product/AttributeOptionTest.php | 109 ++++++++++++------ Test/Unit/Processor/SqlSplitProcessorTest.php | 3 +- 2 files changed, 74 insertions(+), 38 deletions(-) diff --git a/Test/Unit/Component/Product/AttributeOptionTest.php b/Test/Unit/Component/Product/AttributeOptionTest.php index b988247..394fa82 100644 --- a/Test/Unit/Component/Product/AttributeOptionTest.php +++ b/Test/Unit/Component/Product/AttributeOptionTest.php @@ -2,53 +2,88 @@ namespace CtiDigital\Configurator\Test\Unit\Component\Product; use CtiDigital\Configurator\Component\Product\AttributeOption; -use Magento\Eav\Api\Data\AttributeOptionInterfaceFactory; +use Magento\Catalog\Api\ProductAttributeRepositoryInterface; +use Magento\Eav\Api\AttributeOptionManagementInterface; use Magento\Eav\Api\Data\AttributeOptionLabelInterfaceFactory; +use Magento\Eav\Api\Data\AttributeOptionInterfaceFactory; +use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\Catalog\Model\ResourceModel\Eav\Attribute; +use Magento\Eav\Model\Entity\Attribute\Option; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject; -class AttributeOptionTest extends \PHPUnit\Framework\TestCase +class AttributeOptionTest extends TestCase { /** - * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + * @var ProductAttributeRepositoryInterface | PHPUnit_Framework_MockObject_MockObject + */ + private $attrRepository; + + /** + * @var AttributeOptionManagementInterface|MockObject + */ + private $attrOptionManagement; + + /** + * @var AttributeOptionLabelInterfaceFactory|MockObject + */ + private $attrOptionLabelFact; + + /** + * @var AttributeOptionInterfaceFactory|MockObject */ - protected $objectManager; + private $attrOptionFactory; /** - * @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface | \PHPUnit_Framework_MockObject_MockObject + * @var LoggerInterface|MockObject */ - protected $attrRepositoryMock; + private $log; + /** * @var AttributeOption */ - protected $attributeOption; + private $attributeOption; protected function setUp() { - $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->attrRepositoryMock = $this->getMockBuilder('Magento\Catalog\Api\ProductAttributeRepositoryInterface') + $this->attrRepository = $this->getMockBuilder(ProductAttributeRepositoryInterface::class) ->disableOriginalConstructor() ->setMethods(['getList', 'get', 'save', 'delete', 'deleteById', 'getCustomAttributesMetadata']) ->getMock(); - $optionLabelFactory = $this->getMockBuilder(AttributeOptionLabelInterfaceFactory::class)->getMock(); - $optionFactory = $this->getMockBuilder(AttributeOptionInterfaceFactory::class)->getMock(); + $this->attrOptionManagement = $this->getMockBuilder(AttributeOptionManagementInterface::class) + ->disableOriginalConstructor() + ->getMock(); - $this->attributeOption = $this->objectManager->getObject( - AttributeOption::class, - [ - 'attributeRepository' => $this->attrRepositoryMock, - 'optionFactory' => $optionFactory, - 'labelFactory' => $optionLabelFactory - ] + $this->attrOptionLabelFact = $this->getMockBuilder(AttributeOptionLabelInterfaceFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->attrOptionFactory = $this->getMockBuilder(AttributeOptionInterfaceFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->log = $this->getMockBuilder(LoggerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->attributeOption = new AttributeOption( + $this->attrRepository, + $this->attrOptionManagement, + $this->attrOptionLabelFact, + $this->attrOptionFactory, + $this->log ); } public function testAttributeIsDropdown() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', []); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertTrue($this->attributeOption->isOptionAttribute('colour')); @@ -57,10 +92,10 @@ public function testAttributeIsDropdown() public function testAttributeIsMultiSelect() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'multiselect', []); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertTrue($this->attributeOption->isOptionAttribute('colour')); @@ -69,10 +104,10 @@ public function testAttributeIsMultiSelect() public function testAttributeIsNotAllowed() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'text', null); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertFalse($this->attributeOption->isOptionAttribute('colour')); @@ -81,13 +116,13 @@ public function testAttributeIsNotAllowed() public function testAttributeBackendModelIsNotProcessed() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', []); $attributeMock->expects($this->once()) ->method('getBackendModel') ->willReturn('/test/'); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertFalse($this->attributeOption->isOptionAttribute('colour')); @@ -96,10 +131,10 @@ public function testAttributeBackendModelIsNotProcessed() public function testOptionValueDoesNotExist() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', ['Red']); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertFalse($this->attributeOption->isOptionValueExists('colour', 'White')); @@ -108,10 +143,10 @@ public function testOptionValueDoesNotExist() public function testOptionValueExists() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', ['Red']); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $this->assertTrue($this->attributeOption->isOptionValueExists('colour', 'Red')); @@ -120,10 +155,10 @@ public function testOptionValueExists() public function testNewOptionIsNotDuplicated() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', ['Red']); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $newValues = [ @@ -150,10 +185,10 @@ public function testNewOptionIsNotDuplicated() public function testAddOption() { /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeMock + * @var Attribute $attributeMock */ $attributeMock = $this->createMockAttribute('colour', 'select', ['Red', 'Green']); - $this->attrRepositoryMock->expects($this->once()) + $this->attrRepository->expects($this->once()) ->method('get') ->willReturn($attributeMock); $values = [ @@ -171,9 +206,9 @@ public function testAddOption() private function createMockAttribute($code, $input, $values) { /** - * @var \PHPUnit_Framework_MockObject_MockObject $attributeMock + * @var PHPUnit_Framework_MockObject_MockObject $attributeMock */ - $attributeMock = $this->getMockBuilder('Magento\Catalog\Model\ResourceModel\Eav\Attribute') + $attributeMock = $this->getMockBuilder(Attribute::class) ->disableOriginalConstructor() ->setMethods(['getAttributeCode', 'getFrontendInput', 'getOptions', 'getBackendModel', 'getIsUserDefined']) ->getMock(); @@ -186,7 +221,7 @@ private function createMockAttribute($code, $input, $values) if (is_array($values)) { $attributeOptions = []; foreach ($values as $attributeValue) { - $option = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\Option') + $option = $this->getMockBuilder(Option::class) ->disableOriginalConstructor() ->setMethods(['getLabel']) ->getMock(); diff --git a/Test/Unit/Processor/SqlSplitProcessorTest.php b/Test/Unit/Processor/SqlSplitProcessorTest.php index 0537f7b..a869ca3 100644 --- a/Test/Unit/Processor/SqlSplitProcessorTest.php +++ b/Test/Unit/Processor/SqlSplitProcessorTest.php @@ -14,6 +14,7 @@ use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\DB\Adapter\Pdo\Mysql; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Exception; /** * Class SqlSplitProcessorTest @@ -93,7 +94,7 @@ public function testExceptionHandling() $this->mockConnection ->expects($this->any()) ->method('query') - ->willThrowException(new \Exception($exMsg)); + ->willThrowException(new Exception($exMsg)); $this->mockLogger ->expects($this->at(1)) From 943d5bd95c9c82d4105d9f2d973220fd12bff7bc Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 14:12:25 +0000 Subject: [PATCH 36/51] Fix image test. --- Component/Product/Image.php | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Component/Product/Image.php b/Component/Product/Image.php index 027bf5b..1da356d 100644 --- a/Component/Product/Image.php +++ b/Component/Product/Image.php @@ -2,8 +2,10 @@ namespace CtiDigital\Configurator\Component\Product; use CtiDigital\Configurator\Api\LoggerInterface; +use FireGento\FastSimpleImport\Helper\Config; use Magento\Framework\Filesystem; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Http\ZendClientFactory; class Image { @@ -13,7 +15,7 @@ class Image protected $log; /** - * @var \Magento\Framework\Http\ZendClientFactory + * @var ZendClientFactory */ protected $httpClientFactory; @@ -23,7 +25,7 @@ class Image protected $filesystem; /** - * @var \FireGento\FastSimpleImport\Helper\Config + * @var Config */ protected $importerConfig; @@ -34,22 +36,21 @@ class Image /** * Image constructor. - * - * @param LoggerInterface $log * @param Filesystem $filesystem - * @param \FireGento\FastSimpleImport\Helper\Config $importerConfig - * @param \Magento\Framework\Http\ZendClientFactory $httpClientFactory + * @param Config $importerConfig + * @param ZendClientFactory $httpClientFactory + * @param LoggerInterface $log */ public function __construct( - LoggerInterface $log, Filesystem $filesystem, - \FireGento\FastSimpleImport\Helper\Config $importerConfig, - \Magento\Framework\HTTP\ZendClientFactory $httpClientFactory + Config $importerConfig, + ZendClientFactory $httpClientFactory, + LoggerInterface $log ) { - $this->log = $log; $this->filesystem = $filesystem; $this->importerConfig = $importerConfig; $this->httpClientFactory = $httpClientFactory; + $this->log = $log; } /** From b56baef5baaba8f5a9ac00a1dc8a40145d6ae27d Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 14:38:43 +0000 Subject: [PATCH 37/51] Fix issue where the encryption flag wasn't being used when setting website configuration. (#93) --- Component/Config.php | 36 ++++++++++++++++++++---------- Test/Unit/Component/ConfigTest.php | 20 +++++++++++++++++ 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/Component/Config.php b/Component/Config.php index 721fc75..21abaf9 100644 --- a/Component/Config.php +++ b/Component/Config.php @@ -5,6 +5,7 @@ use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Exception\ComponentException; use CtiDigital\Configurator\Api\LoggerInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Encryption\EncryptorInterface; use Magento\Store\Model\StoreFactory; use Magento\Store\Model\WebsiteFactory; @@ -41,6 +42,16 @@ class Config implements ComponentInterface */ protected $encryptor; + /** + * @var WebsiteFactory + */ + protected $websiteFactory; + + /** + * @var StoreFactory + */ + protected $storeFactory; + /** * @var LoggerInterface */ @@ -58,12 +69,16 @@ public function __construct( ScopeConfig $scopeConfig, CollectionFactory $collectionFactory, EncryptorInterface $encryptor, + WebsiteFactory $websiteFactory, + StoreFactory $storeFactory, LoggerInterface $log ) { $this->configResource = $configResource; $this->scopeConfig = $scopeConfig; $this->collectionFactory = $collectionFactory; $this->encryptor = $encryptor; + $this->websiteFactory = $websiteFactory; + $this->storeFactory = $storeFactory; $this->log = $log; } @@ -99,13 +114,12 @@ public function execute($data = null) if ($scope == "websites") { foreach ($configurations as $code => $websiteConfigurations) { - // Handle encryption parameter - $encryption = 0; - if (isset($configuration['encryption']) && $configuration['encryption'] == 1) { - $encryption = 1; - } - foreach ($websiteConfigurations as $configuration) { + // Handle encryption parameter + $encryption = 0; + if (isset($configuration['encryption']) && $configuration['encryption'] == 1) { + $encryption = 1; + } $convertedConfiguration = $this->convert($configuration); $this->setWebsiteConfig( $convertedConfiguration['path'], @@ -146,7 +160,7 @@ private function setGlobalConfig($path, $value, $encrypted = 0) { try { // Check existing value, skip if the same - $scope = \Magento\Framework\App\Config\ScopeConfigInterface::SCOPE_TYPE_DEFAULT; + $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT; $existingValue = $this->scopeConfig->getValue($path, $scope); if ($value == $existingValue) { $this->log->logComment(sprintf("Global Config Already: %s = %s", $path, $value)); @@ -171,9 +185,8 @@ private function setWebsiteConfig($path, $value, $code, $encrypted = 0) $logNest = 1; $scope = 'websites'; - // Prepare Website ID - $websiteFactory = new WebsiteFactory($this->objectManager, \Magento\Store\Model\Website::class); - $website = $websiteFactory->create(); + // Prepare Website ID; + $website = $this->websiteFactory->create(); $website->load($code, 'code'); if (!$website->getId()) { throw new ComponentException(sprintf("There is no website with the code '%s'", $code)); @@ -222,8 +235,7 @@ private function setStoreConfig($path, $value, $code, $encrypted = 0) $logNest = 2; $scope = 'stores'; - $storeFactory = new StoreFactory($this->objectManager, \Magento\Store\Model\Store::class); - $storeView = $storeFactory->create(); + $storeView = $this->storeFactory->create(); $storeView->load($code, 'code'); if (!$storeView->getId()) { throw new ComponentException(sprintf("There is no store view with the code '%s'", $code)); diff --git a/Test/Unit/Component/ConfigTest.php b/Test/Unit/Component/ConfigTest.php index e7ae5a6..d3c4e57 100644 --- a/Test/Unit/Component/ConfigTest.php +++ b/Test/Unit/Component/ConfigTest.php @@ -8,6 +8,8 @@ use Magento\Theme\Model\ResourceModel\Theme\Collection; use Magento\Theme\Model\ResourceModel\Theme\CollectionFactory; use Magento\Framework\Encryption\EncryptorInterface; +use Magento\Store\Model\StoreFactory; +use Magento\Store\Model\WebsiteFactory; use CtiDigital\Configurator\Api\LoggerInterface; class ConfigTest extends \PHPUnit\Framework\TestCase @@ -42,6 +44,16 @@ class ConfigTest extends \PHPUnit\Framework\TestCase */ private $encryptorInterface; + /** + * @var WebsiteFactory|\PHPUnit\Framework\MockObject\MockObject + */ + private $websiteFactory; + + /** + * @var StoreFactory|\PHPUnit\Framework\MockObject\MockObject + */ + private $storeFactory; + /** * @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ @@ -66,6 +78,12 @@ protected function setUp() $this->encryptorInterface = $this->getMockBuilder(EncryptorInterface::class) ->disableOriginalConstructor() ->getMock(); + $this->websiteFactory = $this->getMockBuilder(WebsiteFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->storeFactory = $this->getMockBuilder(StoreFactory::class) + ->disableOriginalConstructor() + ->getMock(); $this->log = $this->getMockBuilder(LoggerInterface::class) ->disableOriginalConstructor() ->getMock(); @@ -74,6 +92,8 @@ protected function setUp() $this->scopeConfig, $this->collectionFactory, $this->encryptorInterface, + $this->websiteFactory, + $this->storeFactory, $this->log ); } From 2c3cc68e97746ed68d635fdd9a2629751f90ee20 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 14:39:17 +0000 Subject: [PATCH 38/51] Check the ignore files flag for environment config. --- Component/Product/Image.php | 4 ++-- Model/Processor.php | 14 +++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Component/Product/Image.php b/Component/Product/Image.php index 1da356d..4ed7eb4 100644 --- a/Component/Product/Image.php +++ b/Component/Product/Image.php @@ -2,10 +2,10 @@ namespace CtiDigital\Configurator\Component\Product; use CtiDigital\Configurator\Api\LoggerInterface; -use FireGento\FastSimpleImport\Helper\Config; use Magento\Framework\Filesystem; use Magento\Framework\App\Filesystem\DirectoryList; -use Magento\Framework\Http\ZendClientFactory; +use FireGento\FastSimpleImport\Helper\Config; +use Magento\Framework\HTTP\ZendClientFactory; class Image { diff --git a/Model/Processor.php b/Model/Processor.php index 5c1c23c..3d1c7d9 100644 --- a/Model/Processor.php +++ b/Model/Processor.php @@ -264,9 +264,17 @@ public function runComponent($componentAlias, $componentConfig) // If there are sources for the environment, process them foreach ((array) $componentConfig['env'][$this->getEnvironment()]['sources'] as $source) { - $sourceType = (isset($componentConfig['type']) === true) ? $componentConfig['type'] : null; - $sourceData = $this->parseData($source, $sourceType); - $component->execute($sourceData); + try { + $sourceType = (isset($componentConfig['type']) === true) ? $componentConfig['type'] : null; + $sourceData = $this->parseData($source, $sourceType); + $component->execute($sourceData); + } catch (ComponentException $e) { + if ($this->isIgnoreMissingFiles() === true) { + $this->log->logInfo("Skipping file {$source} as it could not be found."); + continue; + } + throw $e; + } } } From b9440d68c059614bc043f28ae06d10d2437131e2 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Fri, 10 Jan 2020 14:43:44 +0000 Subject: [PATCH 39/51] Remove unused import statements. --- Component/ApiIntegrations.php | 2 -- Component/CatalogPriceRules.php | 2 -- 2 files changed, 4 deletions(-) diff --git a/Component/ApiIntegrations.php b/Component/ApiIntegrations.php index 4d11204..1ccbc6c 100644 --- a/Component/ApiIntegrations.php +++ b/Component/ApiIntegrations.php @@ -2,8 +2,6 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Api\ComponentInterface; -use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\Serialize\Serializer\Json; use Magento\Integration\Model\IntegrationFactory; use Magento\Integration\Model\Oauth\TokenFactory; use CtiDigital\Configurator\Api\LoggerInterface; diff --git a/Component/CatalogPriceRules.php b/Component/CatalogPriceRules.php index 99e3d2d..6fb0b36 100644 --- a/Component/CatalogPriceRules.php +++ b/Component/CatalogPriceRules.php @@ -9,10 +9,8 @@ use CtiDigital\Configurator\Api\ComponentInterface; use CtiDigital\Configurator\Api\ComponentProcessorInterface; -use Magento\Framework\Serialize\Serializer\Json; use CtiDigital\Configurator\Api\LoggerInterface; use Magento\CatalogRule\Api\Data\RuleInterfaceFactory; -use Magento\Framework\ObjectManagerInterface; /** * Class CatalogPriceRules From b7d6e024ceb43cc112e50a17adf2061f0af24bff Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Tue, 14 Jan 2020 09:47:18 +0000 Subject: [PATCH 40/51] Update tested versions of Magento. Attemp fix for Composer installation issue on Travis. --- .travis.yml | 4 ++-- Test/Integration/setup-magento.sh | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ed9bae5..7f55dd5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,9 +22,9 @@ env: matrix: allow_failures: - php: 7.2 - - env: TEST_SUITE=configurator MAGE_VERSION=2.2.5 - - env: TEST_SUITE=configurator MAGE_VERSION=2.3.1 + - env: TEST_SUITE=configurator MAGE_VERSION=2.2.10 - env: TEST_SUITE=configurator MAGE_VERSION=2.3.2 + - env: TEST_SUITE=configurator MAGE_VERSION=2.3.3 before_install: - echo "{\"http-basic\":{\"repo.magento.com\":{\"username\":\"${MAGENTO_USERNAME}\",\"password\":\"${MAGENTO_PASSWORD}\"}}}" > auth.json diff --git a/Test/Integration/setup-magento.sh b/Test/Integration/setup-magento.sh index 87b589d..15b5d8a 100755 --- a/Test/Integration/setup-magento.sh +++ b/Test/Integration/setup-magento.sh @@ -14,6 +14,8 @@ cd magento2 git checkout tags/$1 -b $1 +# Update symfony/service-contracts as recommended in https://github.com/magento/magento2/issues/24937 +composer update symfony/service-contracts composer install if [ -z "${TRAVIS_TAG}" ]; then From b91f01b295e355cfcdc320d7e319ce10d6f62f94 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Tue, 14 Jan 2020 09:48:40 +0000 Subject: [PATCH 41/51] Revert changes to Travis config. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7f55dd5..ed9bae5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,9 +22,9 @@ env: matrix: allow_failures: - php: 7.2 - - env: TEST_SUITE=configurator MAGE_VERSION=2.2.10 + - env: TEST_SUITE=configurator MAGE_VERSION=2.2.5 + - env: TEST_SUITE=configurator MAGE_VERSION=2.3.1 - env: TEST_SUITE=configurator MAGE_VERSION=2.3.2 - - env: TEST_SUITE=configurator MAGE_VERSION=2.3.3 before_install: - echo "{\"http-basic\":{\"repo.magento.com\":{\"username\":\"${MAGENTO_USERNAME}\",\"password\":\"${MAGENTO_PASSWORD}\"}}}" > auth.json From c7f9fc8f4bac7de1aaca6bb59dd08cf2abbd07ed Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Tue, 14 Jan 2020 10:51:29 +0000 Subject: [PATCH 42/51] Add the cleanup database command when installing Magento. --- Test/Integration/setup-magento.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Test/Integration/setup-magento.sh b/Test/Integration/setup-magento.sh index 15b5d8a..2b94dfe 100755 --- a/Test/Integration/setup-magento.sh +++ b/Test/Integration/setup-magento.sh @@ -26,7 +26,7 @@ else composer require ctidigital/magento2-configurator ${TRAVIS_TAG:1} fi -php bin/magento setup:install --admin-email "test@test.com" --admin-firstname "CTI" --admin-lastname "Test" --admin-password "password123" --admin-user "admin" --backend-frontname admin --base-url "http://configurator.dev" --db-host 127.0.0.1 --db-name configurator --db-user root --session-save files --use-rewrites 1 --use-secure 0 -vvv +php bin/magento setup:install --cleanup-database --admin-email "test@test.com" --admin-firstname "CTI" --admin-lastname "Test" --admin-password "password123" --admin-user "admin" --backend-frontname admin --base-url "http://configurator.dev" --db-host 127.0.0.1 --db-name configurator --db-user root --session-save files --use-rewrites 1 --use-secure 0 -vvv echo Go to app etc folder cd app/etc From 50df811697fb67001918f532435ef03a37a9eab2 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Tue, 14 Jan 2020 11:34:12 +0000 Subject: [PATCH 43/51] Remove check for instance type. --- Component/Widgets.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/Component/Widgets.php b/Component/Widgets.php index 5ecb867..65b0a79 100644 --- a/Component/Widgets.php +++ b/Component/Widgets.php @@ -79,8 +79,6 @@ public function execute($data = null) public function processWidget($widgetData) { try { - $this->validateInstanceType($widgetData['instance_type']); - $widget = $this->findWidgetByInstanceTypeAndTitle($widgetData['instance_type'], $widgetData['title']); $canSave = false; @@ -129,18 +127,6 @@ public function processWidget($widgetData) } } - public function validateInstanceType($instanceType) - { - $this->log->logComment(sprintf("Checking if %s is a valid instance", $instanceType)); - $instanceType = '\\' . $instanceType; - $instance = $this->widgetFactory->create($instanceType); - if (!$instance instanceof $instanceType) { - throw new ComponentException("Instance %s is invalid", $instanceType); - } - $this->log->logComment(sprintf("Found instance %s.", $instanceType)); - // @todo validate parameters somehow using the $fields - } - /** * @param $widgetInstanceType * @param $widgetTitle From a5f051c10cec57f9109aa57a060325d6eca59aef Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Tue, 14 Jan 2020 11:43:19 +0000 Subject: [PATCH 44/51] Fix bug where the logger wasn't being injected. --- Component/AdminRoles.php | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/Component/AdminRoles.php b/Component/AdminRoles.php index 0c0abf6..7002f1f 100644 --- a/Component/AdminRoles.php +++ b/Component/AdminRoles.php @@ -2,22 +2,18 @@ namespace CtiDigital\Configurator\Component; use CtiDigital\Configurator\Api\ComponentInterface; +use CtiDigital\Configurator\Exception\ComponentException; +use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Authorization\Model\RoleFactory; use Magento\Authorization\Model\RulesFactory; -use CtiDigital\Configurator\Api\LoggerInterface; use Magento\Authorization\Model\UserContextInterface; use Magento\Authorization\Model\Acl\Role\Group as RoleGroup; -use CtiDigital\Configurator\Exception\ComponentException; class AdminRoles implements ComponentInterface { protected $alias = 'adminroles'; protected $name = 'Admin Roles'; protected $description = 'Component to create Admin Roles'; - /** - * @var LoggerInterface - */ - protected $log; /** * RoleFactory @@ -33,6 +29,11 @@ class AdminRoles implements ComponentInterface */ protected $rulesFactory; + /** + * @var LoggerInterface + */ + private $log; + /** * AdminRoles constructor. * @param RoleFactory $roleFactory @@ -40,10 +41,12 @@ class AdminRoles implements ComponentInterface */ public function __construct( RoleFactory $roleFactory, - RulesFactory $rulesFactory + RulesFactory $rulesFactory, + LoggerInterface $log ) { $this->roleFactory = $roleFactory; $this->rulesFactory = $rulesFactory; + $this->log = $log; } /** @@ -64,15 +67,6 @@ public function execute($data = null) } } - /** - * @param LoggerInterface $logger - */ - public function setLogger(LoggerInterface $logger) - { - $this->log = $logger; - return $this; - } - /** * Create Admin user roles, or update them if they exist * From 161933f63cc77b95bb1f3a85e6cec0537153b5fc Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Tue, 14 Jan 2020 12:05:16 +0000 Subject: [PATCH 45/51] Fix bug where the parent constructor was not called. --- Component/CustomerAttributes.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Component/CustomerAttributes.php b/Component/CustomerAttributes.php index fecb0a1..13b2cab 100644 --- a/Component/CustomerAttributes.php +++ b/Component/CustomerAttributes.php @@ -79,6 +79,7 @@ public function __construct( Attribute $attributeResource, LoggerInterface $log ) { + parent::__construct($eavSetup, $attributeRepository, $log); $this->attributeConfigMap = array_merge($this->attributeConfigMap, $this->customerConfigMap); $this->customerSetup = $customerSetupFactory; $this->attributeResource = $attributeResource; From 60506045431e78ba204437c98a05cf32857d3ade Mon Sep 17 00:00:00 2001 From: Raj Chevli Date: Tue, 14 Jan 2020 15:28:28 +0000 Subject: [PATCH 46/51] Look to implement Magento's PHPCS ruleset --- .travis.yml | 2 +- README.md | 2 +- composer.json | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index ed9bae5..025f74d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,7 +38,7 @@ install: before_script: - sh -c "if [ '$TEST_SUITE' = 'configurator' ]; then ./Test/Integration/setup-magento.sh $MAGE_VERSION; fi" script: - - sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then php vendor/bin/phpcs --standard=PSR2 Model/ Console/ Test/ Component/ Api/ Exception/; fi" + - sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then php vendor/bin/phpcs --standard=vendor/magento/magento-coding-standard/Magento2/ruleset.xml Model/ Console/ Test/ Component/ Api/ Exception/; fi" - sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then php vendor/bin/phpmd Model/,Console/,Test/,Component/,Api/,Exception/ text cleancode,codesize,controversial,design,naming,unusedcode; fi" - sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then php vendor/bin/phpcpd Model/ Console/ Test/ Component/ Api/ Exception/; fi" - sh -c "if [ '$TEST_SUITE' = 'unit' ]; then php vendor/bin/phpunit --coverage-clover build/logs/clover.xml Test/Unit/; fi" diff --git a/README.md b/README.md index dd8f83e..b1d3aba 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ This is a work in progress and by no means for use with production environments If you are contributing the module, please run the following commands to stand the best chance with Travis CI liking your code. These test include PHP Code Sniffer, PHP Mess Detector, PHP Copy and Paste Detector, PHP Unit ``` -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/Api/ vendor/ctidigital/magento2-configurator/Component/ vendor/ctidigital/magento2-configurator/Exception/ +php vendor/bin/phpcs --standard=vendor/magento/magento-coding-standard/Magento2/ruleset.xml vendor/ctidigital/magento2-configurator/Model/ vendor/ctidigital/magento2-configurator/Console/ vendor/ctidigital/magento2-configurator/Test/ vendor/ctidigital/magento2-configurator/Api/ vendor/ctidigital/magento2-configurator/Component/ vendor/ctidigital/magento2-configurator/Exception/ php vendor/bin/phpmd vendor/ctidigital/magento2-configurator/Model/,vendor/ctidigital/magento2-configurator/Console/,vendor/ctidigital/magento2-configurator/Test/,vendor/ctidigital/magento2-configurator/Api/,vendor/ctidigital/magento2-configurator/Component/,vendor/ctidigital/magento2-configurator/Exception/ 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/Api/ vendor/ctidigital/magento2-configurator/Component/ vendor/ctidigital/magento2-configurator/Exception/ php vendor/bin/phpunit vendor/ctidigital/magento2-configurator/Test/Unit/ diff --git a/composer.json b/composer.json index 6a3d17f..27d63f5 100644 --- a/composer.json +++ b/composer.json @@ -18,9 +18,10 @@ "squizlabs/php_codesniffer": "^3.4", "sebastian/phpcpd": "~3.0 || ~4.0", "satooshi/php-coveralls": "^1.0", - "phpunit/phpunit": "^6.2" + "phpunit/phpunit": "^6.2", + "magento/magento-coding-standard": "5" }, - "version": "2.3.0", + "version": "3.0.0", "autoload": { "files": [ "registration.php" ], "psr-4": { From 927ddfa0eaa28b41613eb54ec8658372f3b24efe Mon Sep 17 00:00:00 2001 From: Raj Chevli Date: Tue, 14 Jan 2020 15:57:40 +0000 Subject: [PATCH 47/51] Quick test at fixing some PHPCS issues --- Component/CatalogPriceRules.php | 3 --- Component/CustomerGroups.php | 3 --- Component/Sql.php | 2 +- Component/Websites.php | 2 +- Console/Command/RunCommand.php | 2 +- Model/Processor.php | 5 ++--- Test/Integration/ShippingTablesRatesTest.php | 5 ++--- 7 files changed, 7 insertions(+), 15 deletions(-) diff --git a/Component/CatalogPriceRules.php b/Component/CatalogPriceRules.php index 6fb0b36..f329e70 100644 --- a/Component/CatalogPriceRules.php +++ b/Component/CatalogPriceRules.php @@ -12,9 +12,6 @@ use CtiDigital\Configurator\Api\LoggerInterface; use Magento\CatalogRule\Api\Data\RuleInterfaceFactory; -/** - * Class CatalogPriceRules - */ class CatalogPriceRules implements ComponentInterface { /** diff --git a/Component/CustomerGroups.php b/Component/CustomerGroups.php index ef98d58..7023d16 100644 --- a/Component/CustomerGroups.php +++ b/Component/CustomerGroups.php @@ -92,12 +92,9 @@ private function createCustomerGroup($groupName, $taxClassId) ->setTaxClassId($taxClassId) ->save(); - $this->log->logInfo( sprintf('Customer Group "%s" created', $groupName) ); - - return; } /** diff --git a/Component/Sql.php b/Component/Sql.php index 59168cf..5a83125 100644 --- a/Component/Sql.php +++ b/Component/Sql.php @@ -12,7 +12,7 @@ use CtiDigital\Configurator\Component\Processor\SqlSplitProcessor; /** - * Class Sql + * Class Sql - Runs raw SQL queries - generally a fallback for when a configurator component is not available. */ class Sql implements ComponentInterface { diff --git a/Component/Websites.php b/Component/Websites.php index 416d228..a0c8238 100644 --- a/Component/Websites.php +++ b/Component/Websites.php @@ -106,7 +106,7 @@ public function execute($data = null) $indexProcess->load('catalog_product_price'); $indexProcess->reindexAll(); } - } catch (ComponentException $e) { + } catch (\Exception $e) { $this->log->logError($e->getMessage()); } } diff --git a/Console/Command/RunCommand.php b/Console/Command/RunCommand.php index 7ba8c38..49030df 100644 --- a/Console/Command/RunCommand.php +++ b/Console/Command/RunCommand.php @@ -103,7 +103,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($output->getVerbosity() > OutputInterface::VERBOSITY_NORMAL) { $output->writeln('Finished Configurator'); } - } catch (ConfiguratorAdapterException $e) { + } catch (\Exception $e) { $output->writeln('' . $e->getMessage() . ''); } } diff --git a/Model/Processor.php b/Model/Processor.php index 3d1c7d9..6b59c78 100644 --- a/Model/Processor.php +++ b/Model/Processor.php @@ -13,8 +13,7 @@ use Symfony\Component\Yaml\Yaml; /** - * Class Processor - * @package CtiDigital\Configurator\Model + * Class Processor - The overarching class that reads and processes the configurator files. * * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ @@ -454,7 +453,7 @@ private function getData($source) { return ($this->isSourceRemote($source) === true) ? $this->getRemoteData($source) : - file_get_contents(BP . '/' . $source); + file_get_contents(BP . '/' . $source); // phpcs:ignore Magento2.Functions.DiscouragedFunction } /** diff --git a/Test/Integration/ShippingTablesRatesTest.php b/Test/Integration/ShippingTablesRatesTest.php index c439f89..e94b939 100644 --- a/Test/Integration/ShippingTablesRatesTest.php +++ b/Test/Integration/ShippingTablesRatesTest.php @@ -8,8 +8,7 @@ use Magento\Framework\DB\Adapter\AdapterInterface; /** - * Class ShippingTablesRatesTest - * @package CtiDigital\Configurator\Component + * Class ShippingTablesRatesTest - Test to run against Shipping Table Rates * @SuppressWarnings(PHPMD.LongVariable) */ class ShippingTablesRatesTest extends \PHPUnit\Framework\TestCase @@ -33,7 +32,7 @@ class ShippingTablesRatesTest extends \PHPUnit\Framework\TestCase * From directory_country_region table * @var array */ - private $regionIdMap = array('BER' => 82); + private $regionIdMap = ['BER' => 82]; /** * @var ShippingTableRates From 2634d0daecd3b983cb70cb23679a5aca5a3ba843 Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Tue, 14 Jan 2020 16:47:33 +0000 Subject: [PATCH 48/51] PHP Code Sniffer fix. --- Component/Attributes.php | 4 ++-- Component/Blocks.php | 10 +++++----- .../CatalogPriceRules/CatalogPriceRulesProcessor.php | 2 +- Component/Categories.php | 6 +++++- Component/Config.php | 4 ++-- Component/Media.php | 6 +++++- Component/Pages.php | 3 ++- Component/Processor/SqlSplitProcessor.php | 3 +++ Component/Product/Image.php | 6 +++++- Component/Widgets.php | 11 ++++++++++- registration.php | 2 +- 11 files changed, 41 insertions(+), 16 deletions(-) diff --git a/Component/Attributes.php b/Component/Attributes.php index 72692ff..6a10cef 100644 --- a/Component/Attributes.php +++ b/Component/Attributes.php @@ -246,11 +246,11 @@ private function manageAttributeOptions($attributeCode, $option) $attributeCode, $e->getMessage() )); - return array(); + return []; } // Loop through existing attributes options - $existingAttributeOptions = array(); + $existingAttributeOptions = []; foreach ($attributeOptions as $attributeOption) { $value = $attributeOption->getLabel(); $existingAttributeOptions[] = $value; diff --git a/Component/Blocks.php b/Component/Blocks.php index 03471a5..732da2e 100644 --- a/Component/Blocks.php +++ b/Component/Blocks.php @@ -86,7 +86,7 @@ private function processBlock($identifier, $blockData) // Check if there are existing blocks if ($blocks->count()) { - $stores = array(); + $stores = []; // Check if stores are specified if (isset($data['stores'])) { @@ -98,7 +98,7 @@ private function processBlock($identifier, $blockData) } // If there is still no block to play with, create a new block object. - if (is_null($block)) { + if ($block === null) { $block = $this->blockFactory->create(); $block->setIdentifier($identifier); $canSave = true; @@ -110,6 +110,7 @@ private function processBlock($identifier, $blockData) if ($key == "source") { $key = 'content'; //TODO load this with Magento's code, and also check for file existing + // phpcs:ignore Magento2.Functions.DiscouragedFunction $value = file_get_contents(BP . '/' . $value); } @@ -147,7 +148,7 @@ private function processBlock($identifier, $blockData) if (isset($data['stores'])) { $block->unsetData('store_id'); $block->unsetData('store_data'); - $stores = array(); + $stores = []; foreach ($data['stores'] as $code) { $stores[] = $this->getStoreByCode($code)->getId(); } @@ -168,7 +169,6 @@ private function processBlock($identifier, $blockData) } } - /** * Find the block to process given the identifier, block collection and optionally stores * @@ -180,7 +180,7 @@ private function processBlock($identifier, $blockData) private function getBlockToProcess( $identifier, \Magento\Cms\Model\ResourceModel\Block\Collection $blocks, - $stores = array() + $stores = [] ) { // If there is only 1 block and stores hasn't been specified if ($blocks->count() == 1 && count($stores) == 0) { diff --git a/Component/CatalogPriceRules/CatalogPriceRulesProcessor.php b/Component/CatalogPriceRules/CatalogPriceRulesProcessor.php index 7ce1044..b480169 100644 --- a/Component/CatalogPriceRules/CatalogPriceRulesProcessor.php +++ b/Component/CatalogPriceRules/CatalogPriceRulesProcessor.php @@ -128,7 +128,7 @@ public function process() $rule = $ruleCollection->getFirstItem(); // If the rule does not exist, create a new one - if (is_null($rule->getId())) { + if ($rule->getId() === null) { $rule = $this->ruleFactory->create(); } diff --git a/Component/Categories.php b/Component/Categories.php index 76fc751..4a8ec38 100644 --- a/Component/Categories.php +++ b/Component/Categories.php @@ -123,10 +123,11 @@ public function getDefaultCategory($store = null) * @param array $categories * @param \Magento\Catalog\Model\Category $parentCategory * @SuppressWarnings(PHPMD) + * @throws \Magento\Framework\Exception\FileSystemException */ public function createOrUpdateCategory( \Magento\Catalog\Model\Category $parentCategory, - $categories = array() + $categories = [] ) { foreach ($categories as $categoryValues) { // Load the category using its name and parent category @@ -147,7 +148,9 @@ public function createOrUpdateCategory( case 'category': break; case 'image': + // phpcs:ignore Magento2.Functions.DiscouragedFunction $img = basename($value); + // phpcs:ignore Magento2.Functions.DiscouragedFunction $path = parse_url($value); $catMediaDir = $this->dirList->getPath('media') . '/' . 'catalog' . '/' . 'category' . '/'; @@ -155,6 +158,7 @@ public function createOrUpdateCategory( $value = BP . '/' . trim($value, '/'); } + // phpcs:ignore if (!@copy($value, $catMediaDir . $img)) { $this->log->logError('Failed to find image: ' . $value, 1); break; diff --git a/Component/Config.php b/Component/Config.php index 21abaf9..84e9f8e 100644 --- a/Component/Config.php +++ b/Component/Config.php @@ -86,10 +86,10 @@ public function __construct( * @param $data * @SuppressWarnings(PHPMD) */ - public function execute($data = null) + public function execute($data = null) //phpcs:ignore Generic.Metrics.NestingLevel { try { - $validScopes = array('global', 'websites', 'stores'); + $validScopes = ['global', 'websites', 'stores']; foreach ($data as $scope => $configurations) { if (!in_array($scope, $validScopes)) { throw new ComponentException(sprintf("This is not a valid scope '%s' in your config.", $scope)); diff --git a/Component/Media.php b/Component/Media.php index 3996d2d..70091e8 100644 --- a/Component/Media.php +++ b/Component/Media.php @@ -84,6 +84,7 @@ private function createChildFolderFileItem($currentPath, $name, $node, $nest = 0 $newPath = $currentPath . DIRECTORY_SEPARATOR . $node['name']; + // phpcs:ignore Magento2.Functions.DiscouragedFunction if (file_exists($newPath)) { $this->log->logComment(sprintf('File already exists: %s', $newPath), $nest); return; @@ -104,10 +105,12 @@ private function createChildFolderFileItem($currentPath, $name, $node, $nest = 0 private function checkAndCreateFolder($newPath, $name, $nest) { // Check if the file/folder exists + // phpcs:ignore Magento2.Functions.DiscouragedFunction if (!file_exists($newPath)) { // If the node does not have a numeric index if (!is_numeric($name)) { // Then it is a directory so create it + // phpcs:ignore Magento2.Functions.DiscouragedFunction mkdir($newPath, $this::FULL_ACCESS, true); $this->log->logInfo(sprintf('Created new media directory %s', $name), $nest); } @@ -129,8 +132,9 @@ private function checkAndCreateFolder($newPath, $name, $nest) private function downloadAndSetFile($path, $node, $nest) { $this->log->logInfo(sprintf('Downloading contents of file from %s', $node['location']), $nest); + // phpcs:ignore Magento2.Functions.DiscouragedFunction $fileContents = file_get_contents($node['location']); - + // phpcs:ignore Magento2.Functions.DiscouragedFunction file_put_contents($path, $fileContents); $this->log->logInfo(sprintf('Created new file: %s', $path), $nest); } diff --git a/Component/Pages.php b/Component/Pages.php index 947e5e3..29b50cf 100644 --- a/Component/Pages.php +++ b/Component/Pages.php @@ -117,6 +117,7 @@ protected function processPage($identifier, $data) // Check if content is from a file source if ($key == "source") { $key = 'content'; + // phpcs:ignore Magento2.Functions.DiscouragedFunction $value = file_get_contents(BP . '/' . $value); } @@ -152,7 +153,7 @@ protected function processPage($identifier, $data) $page->unsetData('store_id'); $page->unsetData('store_data'); - $stores = array(); + $stores = []; foreach ($pageData['stores'] as $code) { $stores[] = $store = $this->storeRepository->get($code)->getId(); } diff --git a/Component/Processor/SqlSplitProcessor.php b/Component/Processor/SqlSplitProcessor.php index 656d3df..d6911fb 100644 --- a/Component/Processor/SqlSplitProcessor.php +++ b/Component/Processor/SqlSplitProcessor.php @@ -94,10 +94,12 @@ private function extractQueriesFromFile($filePath, $delimiter = ';') { $obBaseLevel = ob_get_level(); $queries = []; + // phpcs:ignore Magento2.Functions.DiscouragedFunction $file = fopen($filePath, 'r'); if (is_resource($file) === true) { $query = []; while (feof($file) === false) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction $query[] = fgets($file); if (preg_match('~' . preg_quote($delimiter, '~') . '\s*$~iS', end($query)) === 1) { @@ -116,6 +118,7 @@ private function extractQueriesFromFile($filePath, $delimiter = ';') } } } + // phpcs:ignore Magento2.Functions.DiscouragedFunction fclose($file); return $queries; } diff --git a/Component/Product/Image.php b/Component/Product/Image.php index 4ed7eb4..564e4cd 100644 --- a/Component/Product/Image.php +++ b/Component/Product/Image.php @@ -5,6 +5,7 @@ use Magento\Framework\Filesystem; use Magento\Framework\App\Filesystem\DirectoryList; use FireGento\FastSimpleImport\Helper\Config; +use Magento\Framework\HTTP\ZendClient; use Magento\Framework\HTTP\ZendClientFactory; class Image @@ -89,7 +90,7 @@ public function isValueURL($url) public function downloadFile($value) { /** - * @var \Magento\Framework\HTTP\ZendClient $client + * @var ZendClient $client */ $client = $this->httpClientFactory->create(); $response = ''; @@ -113,6 +114,7 @@ public function downloadFile($value) */ public function getFileName($url) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction $imageName = basename($url); // Remove any URL entities $imageName = urldecode($imageName); @@ -130,7 +132,9 @@ public function getFileName($url) */ public function saveFile($fileName, $value) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction $name = pathinfo($fileName, PATHINFO_FILENAME); + // phpcs:ignore Magento2.Functions.DiscouragedFunction $ext = pathinfo($fileName, PATHINFO_EXTENSION); $writeDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); diff --git a/Component/Widgets.php b/Component/Widgets.php index 65b0a79..61f5ebf 100644 --- a/Component/Widgets.php +++ b/Component/Widgets.php @@ -10,6 +10,7 @@ use Magento\Widget\Model\Widget\InstanceFactory as WidgetInstanceFactory; use Magento\Theme\Model\ResourceModel\Theme\Collection as ThemeCollection; use Magento\Store\Model\StoreFactory; +use Magento\Framework\Serialize\SerializerInterface; class Widgets implements ComponentInterface { @@ -38,6 +39,11 @@ class Widgets implements ComponentInterface */ private $storeFactory; + /** + * @var SerializerInterface + */ + private $serializer; + /** * @var LoggerInterface */ @@ -49,6 +55,7 @@ class Widgets implements ComponentInterface * @param WidgetInstanceFactory $widgetFactory * @param StoreFactory $storeFactory * @param ThemeCollection $themeCollection + * @param SerializerInterface $serializer * @param LoggerInterface $log */ public function __construct( @@ -56,12 +63,14 @@ public function __construct( WidgetInstanceFactory $widgetFactory, StoreFactory $storeFactory, ThemeCollection $themeCollection, + SerializerInterface $serializer, LoggerInterface $log ) { $this->widgetCollection = $collection; $this->widgetFactory = $widgetFactory; $this->themeCollection = $themeCollection; $this->storeFactory = $storeFactory; + $this->serializer = $serializer; $this->log = $log; } @@ -208,7 +217,7 @@ public function getThemeId($themeCode) public function populateWidgetParameters(array $parameters) { // Default property return - return serialize($parameters); + return $this->serializer->serialize($parameters); } /** diff --git a/registration.php b/registration.php index d950686..e22775a 100644 --- a/registration.php +++ b/registration.php @@ -3,4 +3,4 @@ \Magento\Framework\Component\ComponentRegistrar::MODULE, 'CtiDigital_Configurator', __DIR__ -); \ No newline at end of file +); From 95be95ac9aa08963aa04bcecbaec2a8cfdfd94cc Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Wed, 15 Jan 2020 08:45:26 +0000 Subject: [PATCH 49/51] PHP Code Sniffer fix. --- Component/AttributeSets.php | 2 -- Component/Attributes.php | 2 -- .../CatalogPriceRules/CatalogPriceRulesProcessor.php | 3 --- Component/CustomerAttributes.php | 2 -- Component/Pages.php | 6 ------ Component/Processor/SqlSplitProcessor.php | 3 --- Component/Products.php | 3 --- Component/ReviewRating.php | 3 --- Component/TieredPrices.php | 3 --- Model/Processor.php | 8 ++++++-- 10 files changed, 6 insertions(+), 29 deletions(-) diff --git a/Component/AttributeSets.php b/Component/AttributeSets.php index 486e417..ef8764e 100644 --- a/Component/AttributeSets.php +++ b/Component/AttributeSets.php @@ -12,8 +12,6 @@ use Magento\Eav\Model\AttributeSetRepository; /** - * Class AttributeSets - * @package CtiDigital\Configurator\Model\Component * @SuppressWarnings(PHPMD.LongVariable) */ class AttributeSets implements ComponentInterface diff --git a/Component/Attributes.php b/Component/Attributes.php index 6a10cef..914dd2f 100644 --- a/Component/Attributes.php +++ b/Component/Attributes.php @@ -11,8 +11,6 @@ use Magento\Framework\Exception\NoSuchEntityException; /** - * Class Attributes - * @package CtiDigital\Configurator\Model\Component * @SuppressWarnings(PHPMD.LongVariable) */ class Attributes implements ComponentInterface diff --git a/Component/CatalogPriceRules/CatalogPriceRulesProcessor.php b/Component/CatalogPriceRules/CatalogPriceRulesProcessor.php index b480169..2d04349 100644 --- a/Component/CatalogPriceRules/CatalogPriceRulesProcessor.php +++ b/Component/CatalogPriceRules/CatalogPriceRulesProcessor.php @@ -15,9 +15,6 @@ use Magento\CatalogRule\Model\Rule; use Magento\CatalogRule\Model\Rule\Job; -/** - * Class CatalogPriceRulesProcessor - */ class CatalogPriceRulesProcessor implements ComponentProcessorInterface { /** diff --git a/Component/CustomerAttributes.php b/Component/CustomerAttributes.php index 13b2cab..355b5d4 100644 --- a/Component/CustomerAttributes.php +++ b/Component/CustomerAttributes.php @@ -13,8 +13,6 @@ use Magento\Customer\Model\ResourceModel\Attribute; /** - * Class CustomerAttributes - * @package CtiDigital\Configurator\Model\Component * @SuppressWarnings(PHPMD.LongVariable) */ class CustomerAttributes extends Attributes diff --git a/Component/Pages.php b/Component/Pages.php index 29b50cf..2e2c3a6 100644 --- a/Component/Pages.php +++ b/Component/Pages.php @@ -11,12 +11,6 @@ use Magento\Store\Api\StoreRepositoryInterface; use Magento\Store\Model\StoreManagerInterface; -/** - * Class Pages - * Process Magento CMS Pages - * - * @package CtiDigital\Configurator\Model\Component - */ class Pages implements ComponentInterface { protected $alias = 'pages'; diff --git a/Component/Processor/SqlSplitProcessor.php b/Component/Processor/SqlSplitProcessor.php index d6911fb..6d861d2 100644 --- a/Component/Processor/SqlSplitProcessor.php +++ b/Component/Processor/SqlSplitProcessor.php @@ -11,9 +11,6 @@ use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Adapter\AdapterInterface; -/** - * Class SqlSplitProcessor - */ class SqlSplitProcessor { /** diff --git a/Component/Products.php b/Component/Products.php index cd58965..459348a 100644 --- a/Component/Products.php +++ b/Component/Products.php @@ -10,9 +10,6 @@ use CtiDigital\Configurator\Exception\ComponentException; /** - * Class Products - * @package CtiDigital\Configurator\Model\Component - * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ diff --git a/Component/ReviewRating.php b/Component/ReviewRating.php index e7371c1..f60e1db 100644 --- a/Component/ReviewRating.php +++ b/Component/ReviewRating.php @@ -12,9 +12,6 @@ use Magento\Review\Model\Rating\OptionFactory; /** - * Class ReviewRating - * @package CtiDigital\Configurator\Model\Component - * * @SuppressWarnings("CouplingBetweenObjects") */ class ReviewRating implements ComponentInterface diff --git a/Component/TieredPrices.php b/Component/TieredPrices.php index 4332787..0f3b025 100644 --- a/Component/TieredPrices.php +++ b/Component/TieredPrices.php @@ -9,9 +9,6 @@ use FireGento\FastSimpleImport\Model\ImporterFactory; /** - * Class Products - * @package CtiDigital\Configurator\Model\Component - * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class TieredPrices implements ComponentInterface diff --git a/Model/Processor.php b/Model/Processor.php index 6b59c78..f024b94 100644 --- a/Model/Processor.php +++ b/Model/Processor.php @@ -463,8 +463,12 @@ private function getData($source) */ public function getRemoteData($source) { - // phpcs:ignore Magento2.Functions.DiscouragedFunction - $streamContext = stream_context_create(['ssl' => ['verify_peer' => false, 'verify_peer_name' => false]]); + try { + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $streamContext = stream_context_create(['ssl' => ['verify_peer' => false, 'verify_peer_name' => false]]); + } catch (\Exception $e) { + return ''; + } // phpcs:ignore Magento2.Functions.DiscouragedFunction $remoteFile = file_get_contents($source, false, $streamContext); return $remoteFile; From 314c4a36b635ca287e7117504e2c87dd25c7183a Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Wed, 15 Jan 2020 09:03:49 +0000 Subject: [PATCH 50/51] Update sample data. --- Samples/Components/Attributes/attribute_sets.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Samples/Components/Attributes/attribute_sets.yaml b/Samples/Components/Attributes/attribute_sets.yaml index dad9d01..6a8b6c4 100644 --- a/Samples/Components/Attributes/attribute_sets.yaml +++ b/Samples/Components/Attributes/attribute_sets.yaml @@ -1,4 +1,13 @@ attribute_sets: +- + name: Default + inherit: Default + groups: + - + name: General + code: general + attributes: + - color - name: Shirts inherit: Default From 6270399d630c8d0462e70b2b537f4322b89eabde Mon Sep 17 00:00:00 2001 From: Paul Partington Date: Wed, 15 Jan 2020 09:15:40 +0000 Subject: [PATCH 51/51] Update catalog rule example to use JSON. --- Samples/Components/catalog_price_rules.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Samples/Components/catalog_price_rules.yaml b/Samples/Components/catalog_price_rules.yaml index 628d03c..98ae609 100644 --- a/Samples/Components/catalog_price_rules.yaml +++ b/Samples/Components/catalog_price_rules.yaml @@ -1,5 +1,5 @@ config: - apply_all: true + apply_all: true rules: rule1: name: Test Rule @@ -14,8 +14,8 @@ rules: from_date: ### Date format dd/mm/yyyy to_date: 11/10/2021 - conditions_serialized: a:7:{s:4:"type";s:48:"Magento\CatalogRule\Model\Rule\Condition\Combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";s:10:"conditions";a:1:{i:0;a:5:{s:4:"type";s:48:"Magento\CatalogRule\Model\Rule\Condition\Product";s:9:"attribute";s:3:"sku";s:8:"operator";s:2:"==";s:5:"value";s:5:"12asd";s:18:"is_value_processed";b:0;}}} - actions_serialized: a:4:{s:4:"type";s:48:"Magento\CatalogRule\Model\Rule\Action\Collection";s:9:"attribute";N;s:8:"operator";s:1:"=";s:5:"value";N;} + conditions_serialized: '{"type":"Magento\\CatalogRule\\Model\\Rule\\Condition\\Combine","attribute":null,"operator":null,"value":"1","is_value_processed":null,"aggregator":"all","conditions":[{"type":"Magento\\CatalogRule\\Model\\Rule\\Condition\\Product","attribute":"sku","operator":"==","value":"12asd","is_value_processed":false}]}' + actions_serialized: '{"type":"Magento\\CatalogRule\\Model\\Rule\\Action\\Collection","attribute":null,"operator":"=","value":null}' ### Values: [by_fixed|by_percent|to_percent|to_fixed] simple_action: by_fixed ### Range: 0-100 @@ -32,8 +32,8 @@ rules: - 0 from_date: 11/2/2018 to_date: 11/10/2021 - conditions_serialized: a:7:{s:4:"type";s:48:"Magento\CatalogRule\Model\Rule\Condition\Combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";s:10:"conditions";a:1:{i:0;a:5:{s:4:"type";s:48:"Magento\CatalogRule\Model\Rule\Condition\Product";s:9:"attribute";s:3:"sku";s:8:"operator";s:2:"==";s:5:"value";s:5:"12asd";s:18:"is_value_processed";b:0;}}} - actions_serialized: a:4:{s:4:"type";s:48:"Magento\CatalogRule\Model\Rule\Action\Collection";s:9:"attribute";N;s:8:"operator";s:1:"=";s:5:"value";N;} + conditions_serialized: '{"type":"Magento\\CatalogRule\\Model\\Rule\\Condition\\Combine","attribute":null,"operator":null,"value":"1","is_value_processed":null,"aggregator":"all","conditions":[{"type":"Magento\\CatalogRule\\Model\\Rule\\Condition\\Product","attribute":"sku","operator":"==","value":"12asd","is_value_processed":false}]}' + actions_serialized: '{"type":"Magento\\CatalogRule\\Model\\Rule\\Action\\Collection","attribute":null,"operator":"=","value":null}' simple_action: by_percent discount_amount: 100 stop_rules_processing: 1