From 67decd04340d13b1704c0ad7de04b0e64c48f80c Mon Sep 17 00:00:00 2001 From: peterjaap Date: Thu, 7 Dec 2017 08:41:37 +0100 Subject: [PATCH 001/668] Added Visibility and Status filter to category product grid --- .../Block/Adminhtml/Category/Tab/Product.php | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Category/Tab/Product.php b/app/code/Magento/Catalog/Block/Adminhtml/Category/Tab/Product.php index df5894bf4cbd1..20bd1b379beef 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Category/Tab/Product.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Category/Tab/Product.php @@ -14,6 +14,9 @@ use Magento\Backend\Block\Widget\Grid; use Magento\Backend\Block\Widget\Grid\Column; use Magento\Backend\Block\Widget\Grid\Extended; +use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Catalog\Model\Product\Visibility; +use Magento\Framework\App\ObjectManager; class Product extends \Magento\Backend\Block\Widget\Grid\Extended { @@ -29,22 +32,38 @@ class Product extends \Magento\Backend\Block\Widget\Grid\Extended */ protected $_productFactory; + /** + * @var Status + */ + private $status; + + /** + * @var Visibility + */ + private $visibility; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper * @param \Magento\Catalog\Model\ProductFactory $productFactory * @param \Magento\Framework\Registry $coreRegistry * @param array $data + * @param Visibility|null $visibility + * @param Status|null $status */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, \Magento\Catalog\Model\ProductFactory $productFactory, \Magento\Framework\Registry $coreRegistry, - array $data = [] + array $data = [], + Visibility $visibility = null, + Status $status = null ) { $this->_productFactory = $productFactory; $this->_coreRegistry = $coreRegistry; + $this->visibility = $visibility ?: ObjectManager::getInstance()->get(Visibility::class); + $this->status = $status ?: ObjectManager::getInstance()->get(Status::class); parent::__construct($context, $backendHelper, $data); } @@ -102,6 +121,10 @@ protected function _prepareCollection() 'name' )->addAttributeToSelect( 'sku' + )->addAttributeToSelect( + 'visibility' + )->addAttributeToSelect( + 'status' )->addAttributeToSelect( 'price' )->joinField( @@ -159,6 +182,28 @@ protected function _prepareColumns() ); $this->addColumn('name', ['header' => __('Name'), 'index' => 'name']); $this->addColumn('sku', ['header' => __('SKU'), 'index' => 'sku']); + $this->addColumn( + 'visibility', + [ + 'header' => __('Visibility'), + 'index' => 'visibility', + 'type' => 'options', + 'options' => $this->visibility->getOptionArray(), + 'header_css_class' => 'col-visibility', + 'column_css_class' => 'col-visibility' + ] + ); + + $this->addColumn( + 'status', + [ + 'header' => __('Status'), + 'index' => 'status', + 'type' => 'options', + 'options' => $this->status->getOptionArray() + ] + ); + $this->addColumn( 'price', [ From b5b4530d41260ce59d291e660dfbd9f79d57a213 Mon Sep 17 00:00:00 2001 From: Vinay Shah Date: Fri, 26 Jan 2018 22:52:15 +0530 Subject: [PATCH 002/668] magento/magento2#12705: Integrity constraint violation error after reordering product with custom options (issue fixed for 2.2-develop) - Fixed issue by updating options if parent item is same for more than one product - Fixed issue for reorder in admin while checking the availability of product, which is not available in case of associate product. --- .../Model/Order/Reorder/OrderedProductAvailabilityChecker.php | 2 +- app/code/Magento/Quote/Model/Quote/Item.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProductSales/Model/Order/Reorder/OrderedProductAvailabilityChecker.php b/app/code/Magento/ConfigurableProductSales/Model/Order/Reorder/OrderedProductAvailabilityChecker.php index dceb5767edae9..42d7d91fb90e8 100644 --- a/app/code/Magento/ConfigurableProductSales/Model/Order/Reorder/OrderedProductAvailabilityChecker.php +++ b/app/code/Magento/ConfigurableProductSales/Model/Order/Reorder/OrderedProductAvailabilityChecker.php @@ -45,7 +45,7 @@ public function __construct( public function isAvailable(Item $item) { $buyRequest = $item->getBuyRequest(); - $superAttribute = $buyRequest->getData()['super_attribute']; + $superAttribute = $buyRequest->getData()['super_attribute'] ?? []; $connection = $this->getConnection(); $select = $connection->select(); $orderItemParentId = $item->getParentItem()->getProductId(); diff --git a/app/code/Magento/Quote/Model/Quote/Item.php b/app/code/Magento/Quote/Model/Quote/Item.php index d8177ddfe5236..fe6d712500bcd 100644 --- a/app/code/Magento/Quote/Model/Quote/Item.php +++ b/app/code/Magento/Quote/Model/Quote/Item.php @@ -745,6 +745,9 @@ public function saveItemOptions() unset($this->_options[$index]); unset($this->_optionsByCode[$option->getCode()]); } else { + if (!$option->getItem() || !$option->getItem()->getId()) { + $option->setItem($this); + } $option->save(); } } From f0f4101ea0ee823b9aef4383ac3f0fd2327fb307 Mon Sep 17 00:00:00 2001 From: Patrick McLain Date: Sat, 24 Feb 2018 13:27:40 -0500 Subject: [PATCH 003/668] Update/remove packages in composer.json allows compoer install on php71 and php72 --- composer.json | 24 +- composer.lock | 1794 ++++++++++++++++++++++++------------------------- 2 files changed, 881 insertions(+), 937 deletions(-) diff --git a/composer.json b/composer.json index e0db7a4a99a15..a863fedd5cb1a 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", @@ -21,7 +21,6 @@ "ext-iconv": "*", "ext-intl": "*", "ext-mbstring": "*", - "ext-mcrypt": "*", "ext-openssl": "*", "ext-pdo_mysql": "*", "ext-simplexml": "*", @@ -34,9 +33,10 @@ "colinmollenhour/cache-backend-file": "1.4", "colinmollenhour/cache-backend-redis": "1.10.2", "colinmollenhour/credis": "1.6", - "colinmollenhour/php-redis-session-abstract": "~1.2.2", - "composer/composer": "1.4.1", - "magento/composer": "~1.2.0", + "colinmollenhour/php-redis-session-abstract": "~1.3.8", + "composer/composer": "~1.6.0", + "friendsofphp/php-cs-fixer": "~2.10.0", + "magento/composer": "1.3.0.x-dev", "magento/magento-composer-installer": ">=0.1.11", "magento/zendframework1": "~1.13.0", "monolog/monolog": "^1.17", @@ -44,12 +44,13 @@ "pelago/emogrifier": "^2.0.0", "phpseclib/phpseclib": "2.0.*", "ramsey/uuid": "3.6.1", - "sjparkinson/static-review": "~4.1", - "symfony/console": "~2.3, !=2.7.0", - "symfony/event-dispatcher": "~2.1", - "symfony/process": "~2.1", + "sebastian/phpcpd": "~3.0.0", + "symfony/console": "~4.0.0", + "symfony/event-dispatcher": "~4.0.0", + "symfony/process": "~4.0.0", "tedivm/jshrink": "~1.1.0", "tubalmartin/cssmin": "4.1.0", + "webonyx/graphql-php": "^0.11.1", "zendframework/zend-captcha": "^2.7.1", "zendframework/zend-code": "^3.1.0", "zendframework/zend-config": "^2.6.0", @@ -75,16 +76,13 @@ "zendframework/zend-text": "^2.6.0", "zendframework/zend-uri": "^2.5.1", "zendframework/zend-validator": "^2.6.0", - "zendframework/zend-view": "^2.8.1", - "webonyx/graphql-php": "^0.11.1" + "zendframework/zend-view": "^2.8.1" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.1.1", "lusitanian/oauth": "~0.8.10", "pdepend/pdepend": "2.5.0", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.2.0", - "sebastian/phpcpd": "2.0.4", "squizlabs/php_codesniffer": "3.0.1" }, "replace": { diff --git a/composer.lock b/composer.lock index ee6328ed75bb4..5e38e141bcd3c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "9114dbda66ca0958916c9e26caf374ce", + "content-hash": "e0d712daffa20660e5b1c4cbfc459304", "packages": [ { "name": "braintree/braintree_php", @@ -166,21 +166,21 @@ }, { "name": "colinmollenhour/php-redis-session-abstract", - "version": "v1.2.2", + "version": "v1.3.8", "source": { "type": "git", "url": "https://github.com/colinmollenhour/php-redis-session-abstract.git", - "reference": "46968f06eeed7d16e8476d8a1397e224047ac6ff" + "reference": "9f69f5c1be512d5ff168e731e7fa29ab2905d847" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/php-redis-session-abstract/zipball/46968f06eeed7d16e8476d8a1397e224047ac6ff", - "reference": "46968f06eeed7d16e8476d8a1397e224047ac6ff", + "url": "https://api.github.com/repos/colinmollenhour/php-redis-session-abstract/zipball/9f69f5c1be512d5ff168e731e7fa29ab2905d847", + "reference": "9f69f5c1be512d5ff168e731e7fa29ab2905d847", "shasum": "" }, "require": { - "colinmollenhour/credis": "1.6", - "php": "~5.5.0|~5.6.0|~7.0.0|~7.1.0" + "colinmollenhour/credis": "~1.6", + "php": "~5.5.0|~5.6.0|~7.0.0|~7.1.0|~7.2.0" }, "type": "library", "autoload": { @@ -199,7 +199,7 @@ ], "description": "A Redis-based session handler with optimistic locking", "homepage": "https://github.com/colinmollenhour/php-redis-session-abstract", - "time": "2017-04-19T14:21:43+00:00" + "time": "2018-01-08T14:53:13+00:00" }, { "name": "composer/ca-bundle", @@ -259,35 +259,35 @@ }, { "name": "composer/composer", - "version": "1.4.1", + "version": "1.6.3", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "7ee2a5e1cf32e9c8439445fe8dce2c046c2abebd" + "reference": "88a69fda0f2187ad8714cedffd7a8872dceaa4c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/7ee2a5e1cf32e9c8439445fe8dce2c046c2abebd", - "reference": "7ee2a5e1cf32e9c8439445fe8dce2c046c2abebd", + "url": "https://api.github.com/repos/composer/composer/zipball/88a69fda0f2187ad8714cedffd7a8872dceaa4c2", + "reference": "88a69fda0f2187ad8714cedffd7a8872dceaa4c2", "shasum": "" }, "require": { "composer/ca-bundle": "^1.0", "composer/semver": "^1.0", - "composer/spdx-licenses": "^1.0", + "composer/spdx-licenses": "^1.2", "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", "php": "^5.3.2 || ^7.0", "psr/log": "^1.0", "seld/cli-prompt": "^1.0", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.0", - "symfony/console": "^2.7 || ^3.0", - "symfony/filesystem": "^2.7 || ^3.0", - "symfony/finder": "^2.7 || ^3.0", - "symfony/process": "^2.7 || ^3.0" + "symfony/console": "^2.7 || ^3.0 || ^4.0", + "symfony/filesystem": "^2.7 || ^3.0 || ^4.0", + "symfony/finder": "^2.7 || ^3.0 || ^4.0", + "symfony/process": "^2.7 || ^3.0 || ^4.0" }, "require-dev": { - "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit": "^4.8.35 || ^5.7", "phpunit/phpunit-mock-objects": "^2.3 || ^3.0" }, "suggest": { @@ -301,7 +301,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.6-dev" } }, "autoload": { @@ -332,7 +332,7 @@ "dependency", "package" ], - "time": "2017-03-10T08:29:45+00:00" + "time": "2018-01-31T15:28:18+00:00" }, { "name": "composer/semver", @@ -489,39 +489,36 @@ "time": "2017-02-14T19:40:03+00:00" }, { - "name": "justinrainbow/json-schema", - "version": "5.2.6", + "name": "doctrine/annotations", + "version": "v1.6.0", "source": { "type": "git", - "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "d283e11b6e14c6f4664cf080415c4341293e5bbd" + "url": "https://github.com/doctrine/annotations.git", + "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/d283e11b6e14c6f4664cf080415c4341293e5bbd", - "reference": "d283e11b6e14c6f4664cf080415c4341293e5bbd", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", + "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", "shasum": "" }, "require": { - "php": ">=5.3.3" + "doctrine/lexer": "1.*", + "php": "^7.1" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.1", - "json-schema/json-schema-test-suite": "1.2.0", - "phpunit/phpunit": "^4.8.22" + "doctrine/cache": "1.*", + "phpunit/phpunit": "^6.4" }, - "bin": [ - "bin/validate-json" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0.x-dev" + "dev-master": "1.6.x-dev" } }, "autoload": { "psr-4": { - "JsonSchema\\": "src/JsonSchema/" + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" } }, "notification-url": "https://packagist.org/downloads/", @@ -530,55 +527,210 @@ ], "authors": [ { - "name": "Bruno Prieto Reis", - "email": "bruno.p.reis@gmail.com" + "name": "Roman Borschel", + "email": "roman@code-factory.org" }, { - "name": "Justin Rainbow", - "email": "justin.rainbow@gmail.com" + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" }, { - "name": "Igor Wiedler", - "email": "igor@wiedler.ch" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" }, { - "name": "Robert Schönthal", - "email": "seroscho@googlemail.com" + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" } ], - "description": "A library to validate a json schema.", - "homepage": "https://github.com/justinrainbow/json-schema", + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", "keywords": [ - "json", - "schema" + "annotations", + "docblock", + "parser" ], - "time": "2017-10-21T13:15:38+00:00" + "time": "2017-12-06T07:11:42+00:00" }, { - "name": "league/climate", - "version": "2.6.1", + "name": "doctrine/lexer", + "version": "v1.0.1", "source": { "type": "git", - "url": "https://github.com/thephpleague/climate.git", - "reference": "28851c909017424f61cc6a62089316313c645d1c" + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/climate/zipball/28851c909017424f61cc6a62089316313c645d1c", - "reference": "28851c909017424f61cc6a62089316313c645d1c", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", "shasum": "" }, "require": { - "php": ">=5.4.0" + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09T13:34:57+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v2.10.3", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", + "reference": "1634a2c250bf4640f1c5c963f63b413c2d966c8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/1634a2c250bf4640f1c5c963f63b413c2d966c8a", + "reference": "1634a2c250bf4640f1c5c963f63b413c2d966c8a", + "shasum": "" + }, + "require": { + "composer/semver": "^1.4", + "doctrine/annotations": "^1.2", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^5.6 || >=7.0 <7.3", + "php-cs-fixer/diff": "^1.2", + "symfony/console": "^3.2 || ^4.0", + "symfony/event-dispatcher": "^3.0 || ^4.0", + "symfony/filesystem": "^3.0 || ^4.0", + "symfony/finder": "^3.0 || ^4.0", + "symfony/options-resolver": "^3.0 || ^4.0", + "symfony/polyfill-php70": "^1.0", + "symfony/polyfill-php72": "^1.4", + "symfony/process": "^3.0 || ^4.0", + "symfony/stopwatch": "^3.0 || ^4.0" + }, + "conflict": { + "hhvm": "*" + }, + "require-dev": { + "johnkary/phpunit-speedtrap": "^1.1 || ^2.0@dev", + "justinrainbow/json-schema": "^5.0", + "keradus/cli-executor": "^1.0", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.0", + "php-cs-fixer/accessible-object": "^1.0", + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "phpunitgoodpractices/traits": "^1.0", + "symfony/phpunit-bridge": "^3.2.2 || ^4.0" + }, + "suggest": { + "ext-mbstring": "For handling non-UTF8 characters in cache signature.", + "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "classmap": [ + "tests/Test/AbstractFixerTestCase.php", + "tests/Test/AbstractIntegrationCaseFactory.php", + "tests/Test/AbstractIntegrationTestCase.php", + "tests/Test/Assert/AssertTokensTrait.php", + "tests/Test/Constraint/SameStringsConstraint.php", + "tests/Test/IntegrationCase.php", + "tests/Test/IntegrationCaseFactory.php", + "tests/Test/IntegrationCaseFactoryInterface.php", + "tests/Test/InternalIntegrationCaseFactory.php", + "tests/TestCase.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "time": "2018-02-22T16:49:33+00:00" + }, + { + "name": "justinrainbow/json-schema", + "version": "5.2.6", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "d283e11b6e14c6f4664cf080415c4341293e5bbd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/d283e11b6e14c6f4664cf080415c4341293e5bbd", + "reference": "d283e11b6e14c6f4664cf080415c4341293e5bbd", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" }, "require-dev": { - "mockery/mockery": "dev-master", - "phpunit/phpunit": "4.1.*" + "friendsofphp/php-cs-fixer": "^2.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.22" }, + "bin": [ + "bin/validate-json" + ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, "autoload": { "psr-4": { - "League\\CLImate\\": "src/" + "JsonSchema\\": "src/JsonSchema/" } }, "notification-url": "https://packagist.org/downloads/", @@ -587,43 +739,51 @@ ], "authors": [ { - "name": "Joe Tannenbaum", - "email": "hey@joe.codes", - "homepage": "http://joe.codes/", - "role": "Developer" + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" } ], - "description": "PHP's best friend for the terminal. CLImate allows you to easily output colored text, special formats, and more.", + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", "keywords": [ - "cli", - "colors", - "command", - "php", - "terminal" + "json", + "schema" ], - "time": "2015-01-18T14:31:58+00:00" + "time": "2017-10-21T13:15:38+00:00" }, { "name": "magento/composer", - "version": "1.2.0", + "version": "1.3.0.x-dev", "source": { "type": "git", "url": "https://github.com/magento/composer.git", - "reference": "130753af2b755f1967e253deb661225942bb302c" + "reference": "21e4019f051513be041f5611fab717af63b5451e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/composer/zipball/130753af2b755f1967e253deb661225942bb302c", - "reference": "130753af2b755f1967e253deb661225942bb302c", + "url": "https://api.github.com/repos/magento/composer/zipball/21e4019f051513be041f5611fab717af63b5451e", + "reference": "21e4019f051513be041f5611fab717af63b5451e", "shasum": "" }, "require": { - "composer/composer": "1.4.1", - "php": "~5.5.0|~5.6.0|~7.0.0|~7.1.0", - "symfony/console": "~2.3, !=2.7.0" + "composer/composer": "~1.6.0", + "php": "~7.1.3|~7.2.0", + "symfony/console": "~4.0.0" }, "require-dev": { - "phpunit/phpunit": "4.1.0" + "phpunit/phpunit": "~7.0.0" }, "type": "library", "autoload": { @@ -637,7 +797,7 @@ "AFL-3.0" ], "description": "Magento composer library helps to instantiate Composer application and run composer commands.", - "time": "2017-04-24T09:57:02+00:00" + "time": "2018-02-23 15:57:04" }, { "name": "magento/magento-composer-installer", @@ -1022,6 +1182,57 @@ ], "time": "2018-01-05T23:30:21+00:00" }, + { + "name": "php-cs-fixer/diff", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/diff.git", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/78bb099e9c16361126c86ce82ec4405ebab8e756", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "symfony/process": "^3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "SpacePossum" + } + ], + "description": "sebastian/diff v2 backport support for PHP5.6", + "homepage": "https://github.com/PHP-CS-Fixer", + "keywords": [ + "diff" + ], + "time": "2018-02-15T16:58:55+00:00" + }, { "name": "phpseclib/phpseclib", "version": "2.0.9", @@ -1114,6 +1325,55 @@ ], "time": "2017-11-29T06:38:08+00:00" }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26T11:10:40+00:00" + }, { "name": "psr/container", "version": "1.0.0", @@ -1293,8 +1553,140 @@ "time": "2017-03-26T20:37:53+00:00" }, { - "name": "seld/cli-prompt", - "version": "1.0.3", + "name": "sebastian/finder-facade", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/finder-facade.git", + "reference": "4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f", + "reference": "4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f", + "shasum": "" + }, + "require": { + "symfony/finder": "~2.3|~3.0|~4.0", + "theseer/fdomdocument": "~1.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", + "homepage": "https://github.com/sebastianbergmann/finder-facade", + "time": "2017-11-18T17:31:49+00:00" + }, + { + "name": "sebastian/phpcpd", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpcpd.git", + "reference": "dfed51c1288790fc957c9433e2f49ab152e8a564" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/dfed51c1288790fc957c9433e2f49ab152e8a564", + "reference": "dfed51c1288790fc957c9433e2f49ab152e8a564", + "shasum": "" + }, + "require": { + "php": "^5.6|^7.0", + "phpunit/php-timer": "^1.0.6", + "sebastian/finder-facade": "^1.1", + "sebastian/version": "^1.0|^2.0", + "symfony/console": "^2.7|^3.0|^4.0" + }, + "bin": [ + "phpcpd" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Copy/Paste Detector (CPD) for PHP code.", + "homepage": "https://github.com/sebastianbergmann/phpcpd", + "time": "2017-11-16T08:49:28+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "seld/cli-prompt", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/Seldaek/cli-prompt.git", @@ -1433,93 +1825,46 @@ ], "time": "2015-10-13T18:44:15+00:00" }, - { - "name": "sjparkinson/static-review", - "version": "4.1.1", - "source": { - "type": "git", - "url": "https://github.com/sjparkinson/static-review.git", - "reference": "493c3410cf146a12fca84209bad126c494e125f0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sjparkinson/static-review/zipball/493c3410cf146a12fca84209bad126c494e125f0", - "reference": "493c3410cf146a12fca84209bad126c494e125f0", - "shasum": "" - }, - "require": { - "league/climate": "~2.0", - "php": ">=5.4.0", - "symfony/console": "~2.0", - "symfony/process": "~2.0" - }, - "require-dev": { - "mockery/mockery": "~0.9", - "phpunit/phpunit": "~4.0", - "sensiolabs/security-checker": "~2.0", - "squizlabs/php_codesniffer": "~1.0" - }, - "suggest": { - "sensiolabs/security-checker": "Required for ComposerSecurityReview.", - "squizlabs/php_codesniffer": "Required for PhpCodeSnifferReview." - }, - "bin": [ - "bin/static-review.php" - ], - "type": "library", - "autoload": { - "psr-4": { - "StaticReview\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Samuel Parkinson", - "email": "sam.james.parkinson@gmail.com", - "homepage": "http://samp.im" - } - ], - "description": "An extendable framework for version control hooks.", - "abandoned": "phpro/grumphp", - "time": "2014-09-22T08:40:36+00:00" - }, { "name": "symfony/console", - "version": "v2.8.34", + "version": "v4.0.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "162ca7d0ea597599967aa63b23418e747da0896b" + "reference": "36d5b41e7d4e1ccf0370f6babe966c08ef0a1488" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/162ca7d0ea597599967aa63b23418e747da0896b", - "reference": "162ca7d0ea597599967aa63b23418e747da0896b", + "url": "https://api.github.com/repos/symfony/console/zipball/36d5b41e7d4e1ccf0370f6babe966c08ef0a1488", + "reference": "36d5b41e7d4e1ccf0370f6babe966c08ef0a1488", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/debug": "^2.7.2|~3.0.0", + "php": "^7.1.3", "symfony/polyfill-mbstring": "~1.0" }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, "require-dev": { "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1|~3.0.0", - "symfony/process": "~2.1|~3.0.0" + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" }, "suggest": { "psr/log": "For using the console logger", "symfony/event-dispatcher": "", + "symfony/lock": "", "symfony/process": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1546,42 +1891,48 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-01-29T08:54:45+00:00" + "time": "2018-01-29T09:06:29+00:00" }, { - "name": "symfony/debug", - "version": "v3.0.9", + "name": "symfony/event-dispatcher", + "version": "v4.0.4", "source": { "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a" + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "74d33aac36208c4d6757807d9f598f0133a3a4eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/697c527acd9ea1b2d3efac34d9806bf255278b0a", - "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/74d33aac36208c4d6757807d9f598f0133a3a4eb", + "reference": "74d33aac36208c4d6757807d9f598f0133a3a4eb", "shasum": "" }, "require": { - "php": ">=5.5.9", - "psr/log": "~1.0" + "php": "^7.1.3" }, "conflict": { - "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + "symfony/dependency-injection": "<3.4" }, "require-dev": { - "symfony/class-loader": "~2.8|~3.0", - "symfony/http-kernel": "~2.8|~3.0" + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/stopwatch": "~3.4|~4.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\Debug\\": "" + "Symfony\\Component\\EventDispatcher\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -1601,47 +1952,36 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Debug Component", + "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-07-30T07:22:48+00:00" + "time": "2018-01-03T07:38:00+00:00" }, { - "name": "symfony/event-dispatcher", - "version": "v2.8.34", + "name": "symfony/filesystem", + "version": "v3.4.4", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "d64be24fc1eba62f9daace8a8918f797fc8e87cc" + "url": "https://github.com/symfony/filesystem.git", + "reference": "e078773ad6354af38169faf31c21df0f18ace03d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d64be24fc1eba62f9daace8a8918f797fc8e87cc", - "reference": "d64be24fc1eba62f9daace8a8918f797fc8e87cc", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e078773ad6354af38169faf31c21df0f18ace03d", + "reference": "e078773ad6354af38169faf31c21df0f18ace03d", "shasum": "" }, "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.6|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" + "php": "^5.5.9|>=7.0.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" + "Symfony\\Component\\Filesystem\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -1661,22 +2001,22 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony EventDispatcher Component", + "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:36:31+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { - "name": "symfony/filesystem", + "name": "symfony/finder", "version": "v3.4.4", "source": { "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "e078773ad6354af38169faf31c21df0f18ace03d" + "url": "https://github.com/symfony/finder.git", + "reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/e078773ad6354af38169faf31c21df0f18ace03d", - "reference": "e078773ad6354af38169faf31c21df0f18ace03d", + "url": "https://api.github.com/repos/symfony/finder/zipball/613e26310776f49a1773b6737c6bd554b8bc8c6f", + "reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f", "shasum": "" }, "require": { @@ -1690,7 +2030,7 @@ }, "autoload": { "psr-4": { - "Symfony\\Component\\Filesystem\\": "" + "Symfony\\Component\\Finder\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -1710,36 +2050,36 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Filesystem Component", + "description": "Symfony Finder Component", "homepage": "https://symfony.com", "time": "2018-01-03T07:37:34+00:00" }, { - "name": "symfony/finder", - "version": "v3.4.4", + "name": "symfony/options-resolver", + "version": "v4.0.4", "source": { "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f" + "url": "https://github.com/symfony/options-resolver.git", + "reference": "371532a2cfe932f7a3766dd4c45364566def1dd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/613e26310776f49a1773b6737c6bd554b8bc8c6f", - "reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/371532a2cfe932f7a3766dd4c45364566def1dd0", + "reference": "371532a2cfe932f7a3766dd4c45364566def1dd0", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": "^7.1.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "4.0-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\Finder\\": "" + "Symfony\\Component\\OptionsResolver\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -1759,9 +2099,14 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Finder Component", + "description": "Symfony OptionsResolver Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" + "keywords": [ + "config", + "configuration", + "options" + ], + "time": "2018-01-18T22:19:33+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -1823,34 +2168,38 @@ "time": "2018-01-30T19:27:44+00:00" }, { - "name": "symfony/process", - "version": "v2.8.34", + "name": "symfony/polyfill-php70", + "version": "v1.7.0", "source": { "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "905efe90024caa75a2fc93f54e14b26f2a099d96" + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/905efe90024caa75a2fc93f54e14b26f2a099d96", - "reference": "905efe90024caa75a2fc93f54e14b26f2a099d96", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3532bfcd8f933a7816f3a0a59682fc404776600f", + "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f", "shasum": "" }, "require": { - "php": ">=5.3.9" + "paragonie/random_compat": "~1.0|~2.0", + "php": ">=5.3.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "1.7-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\Process\\": "" + "Symfony\\Polyfill\\Php70\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -1859,7 +2208,117 @@ ], "authors": [ { - "name": "Fabien Potencier", + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-01-30T19:27:44+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "8eca20c8a369e069d4f4c2ac9895144112867422" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/8eca20c8a369e069d4f4c2ac9895144112867422", + "reference": "8eca20c8a369e069d4f4c2ac9895144112867422", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-01-31T17:43:24+00:00" + }, + { + "name": "symfony/process", + "version": "v4.0.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "e1712002d81de6f39f854bc5bbd9e9f4bb6345b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/e1712002d81de6f39f854bc5bbd9e9f4bb6345b4", + "reference": "e1712002d81de6f39f854bc5bbd9e9f4bb6345b4", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { @@ -1869,7 +2328,56 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-01-29T08:54:45+00:00" + "time": "2018-01-29T09:06:29+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v4.0.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "d52321f0e2b596bd03b5d1dd6eebe71caa925704" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/d52321f0e2b596bd03b5d1dd6eebe71caa925704", + "reference": "d52321f0e2b596bd03b5d1dd6eebe71caa925704", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "https://symfony.com", + "time": "2018-01-03T07:38:00+00:00" }, { "name": "tedivm/jshrink", @@ -1917,6 +2425,46 @@ ], "time": "2015-07-04T07:35:09+00:00" }, + { + "name": "theseer/fdomdocument", + "version": "1.6.6", + "source": { + "type": "git", + "url": "https://github.com/theseer/fDOMDocument.git", + "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/6e8203e40a32a9c770bcb62fe37e68b948da6dca", + "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "lib-libxml": "*", + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "lead" + } + ], + "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", + "homepage": "https://github.com/theseer/fDOMDocument", + "time": "2017-06-30T11:53:12+00:00" + }, { "name": "tubalmartin/cssmin", "version": "v4.1.0", @@ -3978,56 +4526,43 @@ "time": "2015-06-14T21:17:01+00:00" }, { - "name": "friendsofphp/php-cs-fixer", - "version": "v2.1.3", + "name": "lusitanian/oauth", + "version": "v0.8.10", "source": { "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "d30ca69f8bed931b5c630407f0a98306e33c2c39" + "url": "https://github.com/Lusitanian/PHPoAuthLib.git", + "reference": "09f4af38f17db6938253f4d1b171d537913ac1ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/d30ca69f8bed931b5c630407f0a98306e33c2c39", - "reference": "d30ca69f8bed931b5c630407f0a98306e33c2c39", + "url": "https://api.github.com/repos/Lusitanian/PHPoAuthLib/zipball/09f4af38f17db6938253f4d1b171d537913ac1ed", + "reference": "09f4af38f17db6938253f4d1b171d537913ac1ed", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": "^5.3.6 || >=7.0 <7.2", - "sebastian/diff": "^1.1", - "symfony/console": "^2.3 || ^3.0", - "symfony/event-dispatcher": "^2.1 || ^3.0", - "symfony/filesystem": "^2.4 || ^3.0", - "symfony/finder": "^2.2 || ^3.0", - "symfony/polyfill-php54": "^1.0", - "symfony/polyfill-php55": "^1.3", - "symfony/polyfill-php70": "^1.0", - "symfony/polyfill-xml": "^1.3", - "symfony/process": "^2.3 || ^3.0", - "symfony/stopwatch": "^2.5 || ^3.0" - }, - "conflict": { - "hhvm": "<3.9" + "php": ">=5.3.0" }, "require-dev": { - "gecko-packages/gecko-php-unit": "^2.0", - "justinrainbow/json-schema": "^5.0", - "phpunit/phpunit": "^4.5 || ^5.0", - "satooshi/php-coveralls": "^1.0", - "symfony/phpunit-bridge": "^3.2" + "phpunit/phpunit": "3.7.*", + "predis/predis": "0.8.*@dev", + "squizlabs/php_codesniffer": "2.*", + "symfony/http-foundation": "~2.1" }, "suggest": { - "ext-mbstring": "For handling non-UTF8 characters in cache singature.", - "ext-xml": "For better performance.", - "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." + "ext-openssl": "Allows for usage of secure connections with the stream-based HTTP client.", + "predis/predis": "Allows using the Redis storage backend.", + "symfony/http-foundation": "Allows using the Symfony Session storage backend." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.1-dev" + } }, - "bin": [ - "php-cs-fixer" - ], - "type": "application", "autoload": { - "psr-4": { - "PhpCsFixer\\": "src/" + "psr-0": { + "OAuth": "src", + "OAuth\\Unit": "tests" } }, "notification-url": "https://packagist.org/downloads/", @@ -4036,142 +4571,43 @@ ], "authors": [ { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" + "name": "David Desberg", + "email": "david@daviddesberg.com" }, { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Elliot Chance", + "email": "elliotchance@gmail.com" + }, + { + "name": "Pieter Hordijk", + "email": "info@pieterhordijk.com" } ], - "description": "A tool to automatically fix PHP code style", - "time": "2017-03-31T12:59:38+00:00" + "description": "PHP 5.3+ oAuth 1/2 Library", + "keywords": [ + "Authentication", + "authorization", + "oauth", + "security" + ], + "time": "2016-07-12T22:15:40+00:00" }, { - "name": "ircmaxell/password-compat", - "version": "v1.0.4", + "name": "myclabs/deep-copy", + "version": "1.7.0", "source": { "type": "git", - "url": "https://github.com/ircmaxell/password_compat.git", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", "shasum": "" }, - "require-dev": { - "phpunit/phpunit": "4.*" - }, - "type": "library", - "autoload": { - "files": [ - "lib/password.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Anthony Ferrara", - "email": "ircmaxell@php.net", - "homepage": "http://blog.ircmaxell.com" - } - ], - "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", - "homepage": "https://github.com/ircmaxell/password_compat", - "keywords": [ - "hashing", - "password" - ], - "time": "2014-11-20T16:49:30+00:00" - }, - { - "name": "lusitanian/oauth", - "version": "v0.8.10", - "source": { - "type": "git", - "url": "https://github.com/Lusitanian/PHPoAuthLib.git", - "reference": "09f4af38f17db6938253f4d1b171d537913ac1ed" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Lusitanian/PHPoAuthLib/zipball/09f4af38f17db6938253f4d1b171d537913ac1ed", - "reference": "09f4af38f17db6938253f4d1b171d537913ac1ed", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "3.7.*", - "predis/predis": "0.8.*@dev", - "squizlabs/php_codesniffer": "2.*", - "symfony/http-foundation": "~2.1" - }, - "suggest": { - "ext-openssl": "Allows for usage of secure connections with the stream-based HTTP client.", - "predis/predis": "Allows using the Redis storage backend.", - "symfony/http-foundation": "Allows using the Symfony Session storage backend." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.1-dev" - } - }, - "autoload": { - "psr-0": { - "OAuth": "src", - "OAuth\\Unit": "tests" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "David Desberg", - "email": "david@daviddesberg.com" - }, - { - "name": "Elliot Chance", - "email": "elliotchance@gmail.com" - }, - { - "name": "Pieter Hordijk", - "email": "info@pieterhordijk.com" - } - ], - "description": "PHP 5.3+ oAuth 1/2 Library", - "keywords": [ - "Authentication", - "authorization", - "oauth", - "security" - ], - "time": "2016-07-12T22:15:40+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.7.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" + "require": { + "php": "^5.6 || ^7.0" }, "require-dev": { "doctrine/collections": "^1.0", @@ -4775,55 +5211,6 @@ ], "time": "2015-06-21T13:50:34+00:00" }, - { - "name": "phpunit/php-timer", - "version": "1.0.9", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2017-02-26T11:10:40+00:00" - }, { "name": "phpunit/php-token-stream", "version": "2.0.2", @@ -5294,45 +5681,6 @@ ], "time": "2017-04-03T13:19:02+00:00" }, - { - "name": "sebastian/finder-facade", - "version": "1.2.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/finder-facade.git", - "reference": "4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f", - "reference": "4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f", - "shasum": "" - }, - "require": { - "symfony/finder": "~2.3|~3.0|~4.0", - "theseer/fdomdocument": "~1.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", - "homepage": "https://github.com/sebastianbergmann/finder-facade", - "time": "2017-11-18T17:31:49+00:00" - }, { "name": "sebastian/global-state", "version": "2.0.0", @@ -5476,57 +5824,6 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "time": "2017-03-29T09:07:27+00:00" }, - { - "name": "sebastian/phpcpd", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpcpd.git", - "reference": "24d9a880deadb0b8c9680e9cfe78e30b704225db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/24d9a880deadb0b8c9680e9cfe78e30b704225db", - "reference": "24d9a880deadb0b8c9680e9cfe78e30b704225db", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-timer": ">=1.0.6", - "sebastian/finder-facade": "~1.1", - "sebastian/version": "~1.0|~2.0", - "symfony/console": "~2.7|^3.0", - "theseer/fdomdocument": "~1.4" - }, - "bin": [ - "phpcpd" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Copy/Paste Detector (CPD) for PHP code.", - "homepage": "https://github.com/sebastianbergmann/phpcpd", - "time": "2016-04-17T19:32:49+00:00" - }, { "name": "sebastian/recursion-context", "version": "3.0.0", @@ -5623,79 +5920,36 @@ "time": "2015-07-28T20:34:47+00:00" }, { - "name": "sebastian/version", - "version": "2.0.1", + "name": "squizlabs/php_codesniffer", + "version": "3.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "f9eaf037edf22fdfccf04cb0ab57ebcb1e166219" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/f9eaf037edf22fdfccf04cb0ab57ebcb1e166219", + "reference": "f9eaf037edf22fdfccf04cb0ab57ebcb1e166219", "shasum": "" }, "require": { - "php": ">=5.6" + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "f9eaf037edf22fdfccf04cb0ab57ebcb1e166219" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/f9eaf037edf22fdfccf04cb0ab57ebcb1e166219", - "reference": "f9eaf037edf22fdfccf04cb0ab57ebcb1e166219", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" + "dev-master": "3.x-dev" } }, "notification-url": "https://packagist.org/downloads/", @@ -5779,53 +6033,39 @@ "time": "2018-01-21T19:05:02+00:00" }, { - "name": "symfony/dependency-injection", - "version": "v3.4.4", + "name": "symfony/debug", + "version": "v3.0.9", "source": { "type": "git", - "url": "https://github.com/symfony/dependency-injection.git", - "reference": "4b2717ee2499390e371e1fc7abaf886c1c83e83d" + "url": "https://github.com/symfony/debug.git", + "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/4b2717ee2499390e371e1fc7abaf886c1c83e83d", - "reference": "4b2717ee2499390e371e1fc7abaf886c1c83e83d", + "url": "https://api.github.com/repos/symfony/debug/zipball/697c527acd9ea1b2d3efac34d9806bf255278b0a", + "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", - "psr/container": "^1.0" + "php": ">=5.5.9", + "psr/log": "~1.0" }, "conflict": { - "symfony/config": "<3.3.7", - "symfony/finder": "<3.3", - "symfony/proxy-manager-bridge": "<3.4", - "symfony/yaml": "<3.4" - }, - "provide": { - "psr/container-implementation": "1.0" + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" }, "require-dev": { - "symfony/config": "~3.3|~4.0", - "symfony/expression-language": "~2.8|~3.0|~4.0", - "symfony/yaml": "~3.4|~4.0" - }, - "suggest": { - "symfony/config": "", - "symfony/expression-language": "For using expressions in service container configuration", - "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", - "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", - "symfony/yaml": "" + "symfony/class-loader": "~2.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "3.0-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\DependencyInjection\\": "" + "Symfony\\Component\\Debug\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -5845,302 +6085,48 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony DependencyInjection Component", - "homepage": "https://symfony.com", - "time": "2018-01-29T09:16:57+00:00" - }, - { - "name": "symfony/polyfill-php54", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php54.git", - "reference": "84e2b616c197ef400c6d0556a0606cee7c9e21d5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/84e2b616c197ef400c6d0556a0606cee7c9e21d5", - "reference": "84e2b616c197ef400c6d0556a0606cee7c9e21d5", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php54\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-30T19:27:44+00:00" - }, - { - "name": "symfony/polyfill-php55", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php55.git", - "reference": "168371cb3dfb10e0afde96e7c2688be02470d143" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/168371cb3dfb10e0afde96e7c2688be02470d143", - "reference": "168371cb3dfb10e0afde96e7c2688be02470d143", - "shasum": "" - }, - "require": { - "ircmaxell/password-compat": "~1.0", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php55\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-30T19:27:44+00:00" - }, - { - "name": "symfony/polyfill-php70", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3532bfcd8f933a7816f3a0a59682fc404776600f", - "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f", - "shasum": "" - }, - "require": { - "paragonie/random_compat": "~1.0|~2.0", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php70\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-30T19:27:44+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "8eca20c8a369e069d4f4c2ac9895144112867422" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/8eca20c8a369e069d4f4c2ac9895144112867422", - "reference": "8eca20c8a369e069d4f4c2ac9895144112867422", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-31T17:43:24+00:00" + "time": "2016-07-30T07:22:48+00:00" }, { - "name": "symfony/polyfill-xml", - "version": "v1.7.0", + "name": "symfony/dependency-injection", + "version": "v3.4.4", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-xml.git", - "reference": "fcdfb6e64d21848ee65b6d5d0bc75fcb703b0c83" + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "4b2717ee2499390e371e1fc7abaf886c1c83e83d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-xml/zipball/fcdfb6e64d21848ee65b6d5d0bc75fcb703b0c83", - "reference": "fcdfb6e64d21848ee65b6d5d0bc75fcb703b0c83", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/4b2717ee2499390e371e1fc7abaf886c1c83e83d", + "reference": "4b2717ee2499390e371e1fc7abaf886c1c83e83d", "shasum": "" }, "require": { - "php": ">=5.3.3", - "symfony/polyfill-php72": "~1.4" + "php": "^5.5.9|>=7.0.8", + "psr/container": "^1.0" }, - "type": "metapackage", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } + "conflict": { + "symfony/config": "<3.3.7", + "symfony/finder": "<3.3", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for xml's utf8_encode and utf8_decode functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-30T19:27:44+00:00" - }, - { - "name": "symfony/stopwatch", - "version": "v3.4.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "c865551df7c17e63fc1f09f763db04387f91ae4d" + "provide": { + "psr/container-implementation": "1.0" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/c865551df7c17e63fc1f09f763db04387f91ae4d", - "reference": "c865551df7c17e63fc1f09f763db04387f91ae4d", - "shasum": "" + "require-dev": { + "symfony/config": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/yaml": "~3.4|~4.0" }, - "require": { - "php": "^5.5.9|>=7.0.8" + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" }, "type": "library", "extra": { @@ -6150,7 +6136,7 @@ }, "autoload": { "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" + "Symfony\\Component\\DependencyInjection\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -6170,49 +6156,9 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Stopwatch Component", + "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "theseer/fdomdocument", - "version": "1.6.6", - "source": { - "type": "git", - "url": "https://github.com/theseer/fDOMDocument.git", - "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/6e8203e40a32a9c770bcb62fe37e68b948da6dca", - "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "lib-libxml": "*", - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "lead" - } - ], - "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", - "homepage": "https://github.com/theseer/fDOMDocument", - "time": "2017-06-30T11:53:12+00:00" + "time": "2018-01-29T09:16:57+00:00" }, { "name": "theseer/tokenizer", @@ -6308,12 +6254,13 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { + "magento/composer": 20, "phpmd/phpmd": 0 }, "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", @@ -6322,7 +6269,6 @@ "ext-iconv": "*", "ext-intl": "*", "ext-mbstring": "*", - "ext-mcrypt": "*", "ext-openssl": "*", "ext-pdo_mysql": "*", "ext-simplexml": "*", From 0432bc9cb2c60a41908f1196cae44a43244ffba9 Mon Sep 17 00:00:00 2001 From: Patrick McLain Date: Sun, 11 Feb 2018 09:04:31 -0500 Subject: [PATCH 004/668] Update colinmollenhour/php-redis-session-abstract * Update implementation of `Cm\RedisSession\Handler\ConfigInterface` * Add Redis Sentinel config options to `setup:config:set` command --- .../Session/SaveHandler/Redis/Config.php | 65 +++++++++++++++++++ .../Unit/SaveHandler/Redis/ConfigTest.php | 45 +++++++++++++ .../Setup/Model/ConfigOptionsList/Session.php | 41 +++++++++++- .../Model/ConfigOptionsList/SessionTest.php | 14 +++- 4 files changed, 161 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php index 724f949ca5b23..5a4ed1700da55 100644 --- a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php +++ b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php @@ -100,6 +100,26 @@ class Config implements \Cm\RedisSession\Handler\ConfigInterface */ const PARAM_BREAK_AFTER = 'session/redis/break_after'; + /** + * Configuration path for comma separated list of sentinel servers + */ + const PARAM_SENTINEL_SERVERS = 'session/redis/sentinel_servers'; + + /** + * Configuration path for sentinel master + */ + const PARAM_SENTINEL_MASTER = 'session/redis/sentinel_master'; + + /** + * Configuration path for verify sentinel master flag + */ + const PARAM_SENTINEL_VERIFY_MASTER = 'session/redis/sentinel_verify_master'; + + /** + * Configuration path for number of sentinel connection retries + */ + const PARAM_SENTINEL_CONNECT_RETRIES = 'session/redis/sentinel_connect_retries'; + /** * Cookie lifetime config path */ @@ -115,6 +135,11 @@ class Config implements \Cm\RedisSession\Handler\ConfigInterface */ const SESSION_MAX_LIFETIME = 31536000; + /** + * Try to break lock for at most this many seconds + */ + const DEFAULT_FAIL_AFTER = 15; + /** * Deployment config * @@ -293,4 +318,44 @@ public function getLifetime() } return (int)$this->scopeConfig->getValue(self::XML_PATH_COOKIE_LIFETIME, StoreScopeInterface::SCOPE_STORE); } + + /** + * {@inheritdoc} + */ + public function getSentinelServers() + { + return $this->deploymentConfig->get(self::PARAM_SENTINEL_SERVERS); + } + + /** + * {@inheritdoc} + */ + public function getSentinelMaster() + { + return $this->deploymentConfig->get(self::PARAM_SENTINEL_MASTER); + } + + /** + * {@inheritdoc} + */ + public function getSentinelVerifyMaster() + { + return $this->deploymentConfig->get(self::PARAM_SENTINEL_VERIFY_MASTER); + } + + /** + * {@inheritdoc} + */ + public function getSentinelConnectRetries() + { + return $this->deploymentConfig->get(self::PARAM_SENTINEL_CONNECT_RETRIES); + } + + /** + * {@inheritdoc} + */ + public function getFailAfter() + { + return self::DEFAULT_FAIL_AFTER; + } } diff --git a/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php b/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php index 26f3d4c4c4e89..2859b486ec7a1 100644 --- a/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php +++ b/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php @@ -246,4 +246,49 @@ public function testGetLifetimeFrontend() ->willReturn($expectedLifetime); $this->assertEquals($this->config->getLifetime(), $expectedLifetime); } + + public function testGetSentinelServers() + { + $expected = 'server-1,server-2'; + $this->deploymentConfigMock->expects($this->once()) + ->method('get') + ->with(Config::PARAM_SENTINEL_SERVERS) + ->willReturn($expected); + $this->assertEquals($expected, $this->config->getSentinelServers()); + } + + public function testGetSentinelMaster() + { + $expected = 'master'; + $this->deploymentConfigMock->expects($this->once()) + ->method('get') + ->with(Config::PARAM_SENTINEL_MASTER) + ->willReturn($expected); + $this->assertEquals($this->config->getSentinelMaster(), $expected); + } + + public function testGetSentinelVerifyMaster() + { + $expected = '1'; + $this->deploymentConfigMock->expects($this->once()) + ->method('get') + ->with(Config::PARAM_SENTINEL_VERIFY_MASTER) + ->willReturn($expected); + $this->assertEquals($this->config->getSentinelVerifyMaster(), $expected); + } + + public function testGetSentinelConnectRetries() + { + $expected = '10'; + $this->deploymentConfigMock->expects($this->once()) + ->method('get') + ->willReturn(Config::PARAM_SENTINEL_CONNECT_RETRIES) + ->willReturn($expected); + $this->assertEquals($this->config->getSentinelConnectRetries(), $expected); + } + + public function testGetFailAfter() + { + $this->assertEquals($this->config->getFailAfter(), Config::DEFAULT_FAIL_AFTER); + } } diff --git a/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php b/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php index 3b3fbf33a02e2..c0ec78f046e23 100644 --- a/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php +++ b/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php @@ -37,6 +37,10 @@ class Session implements ConfigOptionsListInterface const INPUT_KEY_SESSION_REDIS_DISABLE_LOCKING = 'session-save-redis-disable-locking'; const INPUT_KEY_SESSION_REDIS_MIN_LIFETIME = 'session-save-redis-min-lifetime'; const INPUT_KEY_SESSION_REDIS_MAX_LIFETIME = 'session-save-redis-max-lifetime'; + const INPUT_KEY_SESSION_REDIS_SENTINEL_SERVERS = 'session-save-redis-sentinel-servers'; + const INPUT_KEY_SESSION_REDIS_SENTINEL_MASTER = 'session-save-redis-sentinel-master'; + const INPUT_KEY_SESSION_REDIS_SENTINEL_VERIFY_MASTER = 'session-save-redis-sentinel-verify-master'; + const INPUT_KEY_SESSION_REDIS_SENTINEL_CONNECT_RETRIES = 'session-save-redis-sentinel-connect-retires'; const CONFIG_PATH_SESSION_REDIS = 'session/redis'; const CONFIG_PATH_SESSION_REDIS_HOST = 'session/redis/host'; @@ -57,6 +61,10 @@ class Session implements ConfigOptionsListInterface const CONFIG_PATH_SESSION_REDIS_DISABLE_LOCKING = 'session/redis/disable_locking'; const CONFIG_PATH_SESSION_REDIS_MIN_LIFETIME = 'session/redis/min_lifetime'; const CONFIG_PATH_SESSION_REDIS_MAX_LIFETIME = 'session/redis/max_lifetime'; + const CONFIG_PATH_SESSION_REDIS_SENTINEL_SERVERS = 'session/redis/sentinel_servers'; + const CONFIG_PATH_SESSION_REDIS_SENTINEL_MASTER = 'session/redis/sentinel_master'; + const CONFIG_PATH_SESSION_REDIS_SENTINEL_VERIFY_MASTER = 'session/redis/sentinel_verify_master'; + const CONFIG_PATH_SESSION_REDIS_SENTINEL_CONNECT_RETRIES = 'session/redis/sentinel_connect_retries'; /** * @var array @@ -80,7 +88,9 @@ class Session implements ConfigOptionsListInterface self::INPUT_KEY_SESSION_REDIS_BOT_LIFETIME => '7200', self::INPUT_KEY_SESSION_REDIS_DISABLE_LOCKING => '0', self::INPUT_KEY_SESSION_REDIS_MIN_LIFETIME => '60', - self::INPUT_KEY_SESSION_REDIS_MAX_LIFETIME => '2592000' + self::INPUT_KEY_SESSION_REDIS_MAX_LIFETIME => '2592000', + self::INPUT_KEY_SESSION_REDIS_SENTINEL_VERIFY_MASTER => '0', + self::INPUT_KEY_SESSION_REDIS_SENTINEL_CONNECT_RETRIES => '5', ]; /** @@ -121,6 +131,11 @@ class Session implements ConfigOptionsListInterface self::INPUT_KEY_SESSION_REDIS_DISABLE_LOCKING => self::CONFIG_PATH_SESSION_REDIS_DISABLE_LOCKING, self::INPUT_KEY_SESSION_REDIS_MIN_LIFETIME => self::CONFIG_PATH_SESSION_REDIS_MIN_LIFETIME, self::INPUT_KEY_SESSION_REDIS_MAX_LIFETIME => self::CONFIG_PATH_SESSION_REDIS_MAX_LIFETIME, + self::INPUT_KEY_SESSION_REDIS_SENTINEL_MASTER => self::CONFIG_PATH_SESSION_REDIS_SENTINEL_MASTER, + self::INPUT_KEY_SESSION_REDIS_SENTINEL_SERVERS => self::CONFIG_PATH_SESSION_REDIS_SENTINEL_SERVERS, + self::INPUT_KEY_SESSION_REDIS_SENTINEL_CONNECT_RETRIES => + self::CONFIG_PATH_SESSION_REDIS_SENTINEL_CONNECT_RETRIES, + self::INPUT_KEY_SESSION_REDIS_SENTINEL_VERIFY_MASTER => self::CONFIG_PATH_SESSION_REDIS_SENTINEL_VERIFY_MASTER, ]; /** @@ -246,6 +261,30 @@ public function getOptions() self::CONFIG_PATH_SESSION_REDIS_MAX_LIFETIME, 'Redis max session lifetime, in seconds' ), + new TextConfigOption( + self::INPUT_KEY_SESSION_REDIS_SENTINEL_MASTER, + TextConfigOption::FRONTEND_WIZARD_TEXT, + self::CONFIG_PATH_SESSION_REDIS_SENTINEL_MASTER, + 'Redis Sentinel master' + ), + new TextConfigOption( + self::INPUT_KEY_SESSION_REDIS_SENTINEL_SERVERS, + TextConfigOption::FRONTEND_WIZARD_TEXT, + self::INPUT_KEY_SESSION_REDIS_SENTINEL_SERVERS, + 'Redis Sentinel servers, comma separated' + ), + new TextConfigOption( + self::INPUT_KEY_SESSION_REDIS_SENTINEL_VERIFY_MASTER, + TextConfigOption::FRONTEND_WIZARD_TEXT, + self::CONFIG_PATH_SESSION_REDIS_SENTINEL_VERIFY_MASTER, + 'Redis Sentinel verify master. Values: false (default), true' + ), + new TextConfigOption( + self::INPUT_KEY_SESSION_REDIS_SENTINEL_CONNECT_RETRIES, + TextConfigOption::FRONTEND_WIZARD_TEXT, + self::CONFIG_PATH_SESSION_REDIS_SENTINEL_CONNECT_RETRIES, + 'Redis Sentinel connect retries.' + ), ]; } diff --git a/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/SessionTest.php b/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/SessionTest.php index d37c07e715482..3b1d3e29e4e56 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/SessionTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/SessionTest.php @@ -32,7 +32,7 @@ protected function setUp() public function testGetOptions() { $options = $this->configList->getOptions(); - $this->assertCount(19, $options); + $this->assertCount(23, $options); $this->assertArrayHasKey(0, $options); $this->assertInstanceOf(SelectConfigOption::class, $options[0]); @@ -156,7 +156,11 @@ public function testCreateConfigWithSessionSaveRedis() 'bot_lifetime' => '', 'disable_locking' => '', 'min_lifetime' => '', - 'max_lifetime' => '' + 'max_lifetime' => '', + 'sentinel_master' => '', + 'sentinel_servers' => '', + 'sentinel_connect_retries' => '', + 'sentinel_verify_master' => '', ] ] @@ -209,7 +213,11 @@ public function testCreateConfigWithRedisInput() 'bot_lifetime' => '', 'disable_locking' => '', 'min_lifetime' => '60', - 'max_lifetime' => '3600' + 'max_lifetime' => '3600', + 'sentinel_master' => '', + 'sentinel_servers' => '', + 'sentinel_connect_retries' => '', + 'sentinel_verify_master' => '', ] ], From 0fa65223dbfbc3b1bba27b32eb4636241c5d6adf Mon Sep 17 00:00:00 2001 From: Patrick McLain Date: Sat, 24 Feb 2018 14:35:55 -0500 Subject: [PATCH 005/668] Remove use of depracated TableHelper Replace references of `Symfony\Console\Helper\TableHelper` with `Symfony\Console\Helper\Table`. `new` was used instead of DI to mirror existing reference in https://github.com/magento/magento2/blob/a083717504f63fd22748fb42d74b63c2906226ef/app/code/Magento/Developer/Console/Command/DiInfoCommand.php#L84 Not sure which is preferred. --- .../Indexer/Console/Command/IndexerStatusCommand.php | 5 +++-- .../Unit/Console/Command/IndexerStatusCommandTest.php | 11 ----------- .../Store/Console/Command/StoreListCommand.php | 5 +++-- .../Store/Console/Command/WebsiteListCommand.php | 5 +++-- .../Unit/Console/Command/StoreListCommandTest.php | 10 ---------- .../Unit/Console/Command/WebsiteListCommandTest.php | 10 ---------- 6 files changed, 9 insertions(+), 37 deletions(-) diff --git a/app/code/Magento/Indexer/Console/Command/IndexerStatusCommand.php b/app/code/Magento/Indexer/Console/Command/IndexerStatusCommand.php index 22acdc6f82bbc..cefb070f60b74 100644 --- a/app/code/Magento/Indexer/Console/Command/IndexerStatusCommand.php +++ b/app/code/Magento/Indexer/Console/Command/IndexerStatusCommand.php @@ -9,6 +9,7 @@ use Symfony\Component\Console\Output\OutputInterface; use Magento\Framework\Indexer; use Magento\Framework\Mview; +use Symfony\Component\Console\Helper\Table; /** * Command for displaying status of indexers. @@ -32,7 +33,7 @@ protected function configure() */ protected function execute(InputInterface $input, OutputInterface $output) { - $table = $this->getHelperSet()->get('table'); + $table = new Table($output); $table->setHeaders(['Title', 'Status', 'Update On', 'Schedule Status', 'Schedule Updated']); $rows = []; @@ -63,7 +64,7 @@ protected function execute(InputInterface $input, OutputInterface $output) }); $table->addRows($rows); - $table->render($output); + $table->render(); } /** diff --git a/app/code/Magento/Indexer/Test/Unit/Console/Command/IndexerStatusCommandTest.php b/app/code/Magento/Indexer/Test/Unit/Console/Command/IndexerStatusCommandTest.php index a79c9cc47a1bc..8498bd183af21 100644 --- a/app/code/Magento/Indexer/Test/Unit/Console/Command/IndexerStatusCommandTest.php +++ b/app/code/Magento/Indexer/Test/Unit/Console/Command/IndexerStatusCommandTest.php @@ -8,8 +8,6 @@ use Magento\Framework\Indexer\StateInterface; use Magento\Indexer\Console\Command\IndexerStatusCommand; use Symfony\Component\Console\Tester\CommandTester; -use Symfony\Component\Console\Helper\HelperSet; -use Symfony\Component\Console\Helper\TableHelper; class IndexerStatusCommandTest extends AbstractIndexerCommandCommonSetup { @@ -93,15 +91,6 @@ public function testExecuteAll(array $indexers) $this->initIndexerCollectionByItems($indexerMocks); $this->command = new IndexerStatusCommand($this->objectManagerFactory); - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - - $this->command->setHelperSet( - $objectManager->getObject( - HelperSet::class, - ['helpers' => [$objectManager->getObject(TableHelper::class)]] - ) - ); - $commandTester = new CommandTester($this->command); $commandTester->execute([]); diff --git a/app/code/Magento/Store/Console/Command/StoreListCommand.php b/app/code/Magento/Store/Console/Command/StoreListCommand.php index aaaa8afb76fd2..fcd9600aac684 100644 --- a/app/code/Magento/Store/Console/Command/StoreListCommand.php +++ b/app/code/Magento/Store/Console/Command/StoreListCommand.php @@ -6,6 +6,7 @@ */ namespace Magento\Store\Console\Command; +use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Command\Command; @@ -48,7 +49,7 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { try { - $table = $this->getHelperSet()->get('table'); + $table = new Table($output); $table->setHeaders(['ID', 'Website ID', 'Group ID', 'Name', 'Code', 'Sort Order', 'Is Active']); foreach ($this->storeManager->getStores(true, true) as $store) { @@ -63,7 +64,7 @@ protected function execute(InputInterface $input, OutputInterface $output) ]); } - $table->render($output); + $table->render(); return \Magento\Framework\Console\Cli::RETURN_SUCCESS; } catch (\Exception $e) { diff --git a/app/code/Magento/Store/Console/Command/WebsiteListCommand.php b/app/code/Magento/Store/Console/Command/WebsiteListCommand.php index ce0359d1bb799..985a6402e4e2f 100644 --- a/app/code/Magento/Store/Console/Command/WebsiteListCommand.php +++ b/app/code/Magento/Store/Console/Command/WebsiteListCommand.php @@ -6,6 +6,7 @@ */ namespace Magento\Store\Console\Command; +use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Command\Command; @@ -48,7 +49,7 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { try { - $table = $this->getHelperSet()->get('table'); + $table = new Table($output); $table->setHeaders(['ID', 'Default Group Id', 'Name', 'Code', 'Sort Order', 'Is Default']); foreach ($this->manager->getList() as $website) { @@ -62,7 +63,7 @@ protected function execute(InputInterface $input, OutputInterface $output) ]); } - $table->render($output); + $table->render(); return \Magento\Framework\Console\Cli::RETURN_SUCCESS; } catch (\Exception $e) { diff --git a/app/code/Magento/Store/Test/Unit/Console/Command/StoreListCommandTest.php b/app/code/Magento/Store/Test/Unit/Console/Command/StoreListCommandTest.php index 4f848def8c353..50ea2947c1bd2 100644 --- a/app/code/Magento/Store/Test/Unit/Console/Command/StoreListCommandTest.php +++ b/app/code/Magento/Store/Test/Unit/Console/Command/StoreListCommandTest.php @@ -8,7 +8,6 @@ use Magento\Store\Console\Command\StoreListCommand; use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Helper\HelperSet; -use Symfony\Component\Console\Helper\TableHelper; use Magento\Store\Model\Store; use Magento\Framework\Console\Cli; @@ -42,15 +41,6 @@ protected function setUp() StoreListCommand::class, ['storeManager' => $this->storeManagerMock] ); - - /** @var HelperSet $helperSet */ - $helperSet = $this->objectManager->getObject( - HelperSet::class, - ['helpers' => [$this->objectManager->getObject(TableHelper::class)]] - ); - - //Inject table helper for output - $this->command->setHelperSet($helperSet); } public function testExecuteExceptionNoVerbosity() diff --git a/app/code/Magento/Store/Test/Unit/Console/Command/WebsiteListCommandTest.php b/app/code/Magento/Store/Test/Unit/Console/Command/WebsiteListCommandTest.php index 3978f49522224..0312c735c6772 100644 --- a/app/code/Magento/Store/Test/Unit/Console/Command/WebsiteListCommandTest.php +++ b/app/code/Magento/Store/Test/Unit/Console/Command/WebsiteListCommandTest.php @@ -8,7 +8,6 @@ use Magento\Store\Console\Command\WebsiteListCommand; use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Helper\HelperSet; -use Symfony\Component\Console\Helper\TableHelper; use Magento\Store\Model\Website; use Magento\Framework\Console\Cli; use Magento\Store\Api\WebsiteRepositoryInterface; @@ -43,15 +42,6 @@ protected function setUp() WebsiteListCommand::class, ['websiteManagement' => $this->websiteRepositoryMock] ); - - /** @var HelperSet $helperSet */ - $helperSet = $this->objectManager->getObject( - HelperSet::class, - ['helpers' => [$this->objectManager->getObject(TableHelper::class)]] - ); - - //Inject table helper for output - $this->command->setHelperSet($helperSet); } public function testExecuteExceptionNoVerbosity() From fc3f13f677848037d8b8c16cb62d7ea54ab353f4 Mon Sep 17 00:00:00 2001 From: Patrick McLain Date: Sat, 24 Feb 2018 15:11:06 -0500 Subject: [PATCH 006/668] Fix reference to removed Diaglog console helper It is replaced with `Symfony\Console\Helper\QuestionHelper` --- .../Setup/Console/Command/ConfigSetCommand.php | 9 +++++---- .../Unit/Console/Command/ConfigSetCommandTest.php | 12 ++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php b/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php index 4192d22524ad1..579583e8b1222 100644 --- a/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php +++ b/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php @@ -12,6 +12,7 @@ use Magento\Setup\Model\ConfigModel; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\Question; class ConfigSetCommand extends AbstractSetupCommand { @@ -81,11 +82,11 @@ protected function execute(InputInterface $input, OutputInterface $output) $currentValue = $this->deploymentConfig->get($option->getConfigPath()); if (($currentValue !== null) && ($inputOptions[$option->getName()] !== null)) { - $dialog = $this->getHelperSet()->get('dialog'); - if (!$dialog->askConfirmation( - $output, + $dialog = $this->getHelperSet()->get('question'); + $question = new Question( 'Overwrite the existing configuration for ' . $option->getName() . '?[Y/n]' - )) { + ); + if (strtolower($dialog->ask($input, $output, $question)) !== 'y') { $inputOptions[$option->getName()] = null; } } diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php index 3c89cc0f04bf8..611a99d018ab9 100644 --- a/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php @@ -72,7 +72,7 @@ public function testExecuteInteractiveWithYes() ->expects($this->once()) ->method('process') ->with(['db-host' => 'host']); - $this->checkInteraction(true); + $this->checkInteraction('Y'); } public function testExecuteInteractiveWithNo() @@ -85,21 +85,21 @@ public function testExecuteInteractiveWithNo() ->expects($this->once()) ->method('process') ->with([]); - $this->checkInteraction(false); + $this->checkInteraction('n'); } /** * Checks interaction with users on CLI * - * @param bool $interactionType + * @param string $interactionType * @return void */ private function checkInteraction($interactionType) { - $dialog = $this->createMock(\Symfony\Component\Console\Helper\DialogHelper::class); + $dialog = $this->createMock(\Symfony\Component\Console\Helper\QuestionHelper::class); $dialog ->expects($this->once()) - ->method('askConfirmation') + ->method('ask') ->will($this->returnValue($interactionType)); /** @var \Symfony\Component\Console\Helper\HelperSet|\PHPUnit_Framework_MockObject_MockObject $helperSet */ @@ -107,7 +107,7 @@ private function checkInteraction($interactionType) $helperSet ->expects($this->once()) ->method('get') - ->with('dialog') + ->with('question') ->will($this->returnValue($dialog)); $this->command->setHelperSet($helperSet); From 06b1f785da3bbb473bd01433769ca8509bffe43f Mon Sep 17 00:00:00 2001 From: Patrick McLain Date: Sat, 24 Feb 2018 15:29:37 -0500 Subject: [PATCH 007/668] Remove mocking of Final class `Symfony\Component\Console\Helper\ProgressBar` has been declared Final and cannot be mocked. --- .../Console/Command/DiCompileCommandTest.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/DiCompileCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/DiCompileCommandTest.php index 388aa0670e069..567417308dd19 100644 --- a/setup/src/Magento/Setup/Test/Unit/Console/Command/DiCompileCommandTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/DiCompileCommandTest.php @@ -41,6 +41,12 @@ class DiCompileCommandTest extends \PHPUnit\Framework\TestCase /** @var \Magento\Framework\Component\ComponentRegistrar|\PHPUnit_Framework_MockObject_MockObject */ private $componentRegistrarMock; + /** @var \Symfony\Component\Console\Output\OutputInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $outputMock; + + /** @var \Symfony\Component\Console\Formatter\OutputFormatterInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $outputFormatterMock; + public function setUp() { $this->deploymentConfigMock = $this->createMock(\Magento\Framework\App\DeploymentConfig::class); @@ -74,6 +80,13 @@ public function setUp() [ComponentRegistrar::LIBRARY, ['/path/to/library/one', '/path/to/library/two']], ]); + $this->outputFormatterMock = $this->createMock( + \Symfony\Component\Console\Formatter\OutputFormatterInterface::class + ); + $this->outputMock = $this->createMock(\Symfony\Component\Console\Output\OutputInterface::class); + $this->outputMock->method('getFormatter') + ->willReturn($this->outputFormatterMock); + $this->command = new DiCompileCommand( $this->deploymentConfigMock, $this->directoryListMock, @@ -116,11 +129,7 @@ public function testExecute() ->method('get') ->with(\Magento\Framework\Config\ConfigOptionsListConstants::KEY_MODULES) ->willReturn(['Magento_Catalog' => 1]); - $progressBar = $this->getMockBuilder( - \Symfony\Component\Console\Helper\ProgressBar::class - ) - ->disableOriginalConstructor() - ->getMock(); + $progressBar = new \Symfony\Component\Console\Helper\ProgressBar($this->outputMock); $this->objectManagerMock->expects($this->once())->method('configure'); $this->objectManagerMock From 7c4e41b0c50b52a23a11e2c735d8af74a85fd3c3 Mon Sep 17 00:00:00 2001 From: Patrick McLain Date: Sat, 24 Feb 2018 15:35:33 -0500 Subject: [PATCH 008/668] Correct default argument type in MultipleStreamOutput The second constructor argument of parent class `Symfony\Component\Console\Output\Output` must be boolean. --- setup/src/Magento/Setup/Model/Cron/MultipleStreamOutput.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/src/Magento/Setup/Model/Cron/MultipleStreamOutput.php b/setup/src/Magento/Setup/Model/Cron/MultipleStreamOutput.php index 29392daecb8fd..1823d3aea720b 100644 --- a/setup/src/Magento/Setup/Model/Cron/MultipleStreamOutput.php +++ b/setup/src/Magento/Setup/Model/Cron/MultipleStreamOutput.php @@ -29,7 +29,7 @@ class MultipleStreamOutput extends Output public function __construct( array $streams, $verbosity = self::VERBOSITY_NORMAL, - $decorated = null, + $decorated = false, OutputFormatterInterface $formatter = null ) { foreach ($streams as $stream) { From 49a278a6f141300b66f46044ce4b80ac676090c3 Mon Sep 17 00:00:00 2001 From: Patrick McLain Date: Sat, 24 Feb 2018 15:43:10 -0500 Subject: [PATCH 009/668] Correct comparison logic in ConfigSetCommandTest --- .../Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php index 611a99d018ab9..19d2873b54586 100644 --- a/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php @@ -113,7 +113,7 @@ private function checkInteraction($interactionType) $commandTester = new CommandTester($this->command); $commandTester->execute(['--db-host' => 'host']); - if ($interactionType) { + if (strtolower($interactionType) === 'y') { $message = 'You saved the new configuration.' . PHP_EOL; } else { $message = 'You made no changes to the configuration.'.PHP_EOL; From d8c59beaf43c075d270b5982f1b72226cf0e2fa8 Mon Sep 17 00:00:00 2001 From: Marcin Szterling Date: Wed, 17 Jan 2018 22:34:45 +0000 Subject: [PATCH 010/668] [MAGETWO-1556] Export: Unable to Filter Data by Attribute With Input Type Multiple Select - added support for multiselect attribute for both product and customer entity --- .../ImportExport/Block/Adminhtml/Export/Filter.php | 8 ++++++-- app/code/Magento/ImportExport/Model/Export.php | 5 ++++- .../Model/Export/Entity/AbstractEav.php | 13 ++++++++++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php b/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php index 94dc0ee7493b0..dc928b4c7942d 100644 --- a/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php +++ b/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php @@ -142,7 +142,7 @@ protected function _getMultiSelectHtmlWithValue(Attribute $attribute, $value) if ($attribute->getFilterOptions()) { $options = $attribute->getFilterOptions(); } else { - $options = $attribute->getSource()->getAllOptions(false); + $options = $attribute->getSource()->getAllOptions(); foreach ($options as $key => $optionParams) { if ('' === $optionParams['value']) { @@ -151,12 +151,13 @@ protected function _getMultiSelectHtmlWithValue(Attribute $attribute, $value) } } } + if ($size = count($options)) { $arguments = [ 'name' => $this->getFilterElementName($attribute->getAttributeCode()) . '[]', 'id' => $this->getFilterElementId($attribute->getAttributeCode()), 'class' => 'multiselect multiselect-export-filter', - 'extra_params' => 'multiple="multiple" size="' . ($size > 5 ? 5 : ($size < 2 ? 2 : $size)), + 'extra_params' => 'multiple="multiple" size="' . ($size > 5 ? 5 : ($size < 2 ? 2 : $size)) . '"', ]; /** @var $selectBlock \Magento\Framework\View\Element\Html\Select */ $selectBlock = $this->_layout->createBlock( @@ -364,6 +365,9 @@ public function decorateFilter($value, Attribute $row, \Magento\Framework\DataOb case \Magento\ImportExport\Model\Export::FILTER_TYPE_SELECT: $cell = $this->_getSelectHtmlWithValue($row, $value); break; + case \Magento\ImportExport\Model\Export::FILTER_TYPE_MULTISELECT: + $cell = $this->_getMultiSelectHtmlWithValue($row, $value); + break; case \Magento\ImportExport\Model\Export::FILTER_TYPE_INPUT: $cell = $this->_getInputHtmlWithValue($row, $value); break; diff --git a/app/code/Magento/ImportExport/Model/Export.php b/app/code/Magento/ImportExport/Model/Export.php index 9b0139ff911ce..4719f05dd8b64 100644 --- a/app/code/Magento/ImportExport/Model/Export.php +++ b/app/code/Magento/ImportExport/Model/Export.php @@ -30,6 +30,8 @@ class Export extends \Magento\ImportExport\Model\AbstractModel */ const FILTER_TYPE_SELECT = 'select'; + const FILTER_TYPE_MULTISELECT ='multiselect'; + const FILTER_TYPE_INPUT = 'input'; const FILTER_TYPE_DATE = 'date'; @@ -215,7 +217,8 @@ public function filterAttributeCollection(\Magento\Framework\Data\Collection $co public static function getAttributeFilterType(\Magento\Eav\Model\Entity\Attribute $attribute) { if ($attribute->usesSource() || $attribute->getFilterOptions()) { - return self::FILTER_TYPE_SELECT; + return 'multiselect' == $attribute->getFrontendInput() ? + self::FILTER_TYPE_MULTISELECT : self::FILTER_TYPE_SELECT; } elseif ('datetime' == $attribute->getBackendType()) { return self::FILTER_TYPE_DATE; } elseif ('decimal' == $attribute->getBackendType() || 'int' == $attribute->getBackendType()) { diff --git a/app/code/Magento/ImportExport/Model/Export/Entity/AbstractEav.php b/app/code/Magento/ImportExport/Model/Export/Entity/AbstractEav.php index 5ade67bbf894e..df556e961d2ce 100644 --- a/app/code/Magento/ImportExport/Model/Export/Entity/AbstractEav.php +++ b/app/code/Magento/ImportExport/Model/Export/Entity/AbstractEav.php @@ -152,7 +152,6 @@ public function filterEntityCollection(AbstractCollection $collection) // filter applying if (isset($exportFilter[$attributeCode])) { $attributeFilterType = Export::getAttributeFilterType($attribute); - if (Export::FILTER_TYPE_SELECT == $attributeFilterType) { if (is_scalar($exportFilter[$attributeCode]) && trim($exportFilter[$attributeCode])) { $collection->addAttributeToFilter( @@ -160,6 +159,18 @@ public function filterEntityCollection(AbstractCollection $collection) ['eq' => $exportFilter[$attributeCode]] ); } + } elseif (Export::FILTER_TYPE_MULTISELECT == $attributeFilterType) { + if (is_array($exportFilter[$attributeCode])) { + array_filter($exportFilter[$attributeCode]); + if (!empty($exportFilter[$attributeCode])) { + foreach ($exportFilter[$attributeCode] as $val) { + $collection->addAttributeToFilter( + $attributeCode, + ['finset' => $val] + ); + } + } + } } elseif (Export::FILTER_TYPE_INPUT == $attributeFilterType) { if (is_scalar($exportFilter[$attributeCode]) && trim($exportFilter[$attributeCode])) { $collection->addAttributeToFilter( From 6f88d3fc9be68de05e90b43a4f89077af65e79f4 Mon Sep 17 00:00:00 2001 From: Marcin Szterling Date: Thu, 18 Jan 2018 12:16:12 +0000 Subject: [PATCH 011/668] GETWO-1556] Export: Unable to Filter Data by Attribute With Input Type Multiple Select - reduced complexity of getAttributeFilterType method --- .../Magento/ImportExport/Model/Export.php | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/ImportExport/Model/Export.php b/app/code/Magento/ImportExport/Model/Export.php index 4719f05dd8b64..11acd68cb1e01 100644 --- a/app/code/Magento/ImportExport/Model/Export.php +++ b/app/code/Magento/ImportExport/Model/Export.php @@ -30,7 +30,7 @@ class Export extends \Magento\ImportExport\Model\AbstractModel */ const FILTER_TYPE_SELECT = 'select'; - const FILTER_TYPE_MULTISELECT ='multiselect'; + const FILTER_TYPE_MULTISELECT = 'multiselect'; const FILTER_TYPE_INPUT = 'input'; @@ -67,6 +67,17 @@ class Export extends \Magento\ImportExport\Model\AbstractModel */ protected $_exportAdapterFac; + /** + * @var array + */ + public static $backendTypeToFilterMapper = [ + 'datetime' => self::FILTER_TYPE_DATE, + 'decimal' => self::FILTER_TYPE_NUMBER, + 'int' => self::FILTER_TYPE_NUMBER, + 'varchar' => self::FILTER_TYPE_INPUT, + 'text' => self::FILTER_TYPE_INPUT + ]; + /** * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Filesystem $filesystem @@ -82,7 +93,8 @@ public function __construct( \Magento\ImportExport\Model\Export\Entity\Factory $entityFactory, \Magento\ImportExport\Model\Export\Adapter\Factory $exportAdapterFac, array $data = [] - ) { + ) + { $this->_exportConfig = $exportConfig; $this->_entityFactory = $entityFactory; $this->_exportAdapterFac = $exportAdapterFac; @@ -219,19 +231,19 @@ public static function getAttributeFilterType(\Magento\Eav\Model\Entity\Attribut if ($attribute->usesSource() || $attribute->getFilterOptions()) { return 'multiselect' == $attribute->getFrontendInput() ? self::FILTER_TYPE_MULTISELECT : self::FILTER_TYPE_SELECT; - } elseif ('datetime' == $attribute->getBackendType()) { - return self::FILTER_TYPE_DATE; - } elseif ('decimal' == $attribute->getBackendType() || 'int' == $attribute->getBackendType()) { - return self::FILTER_TYPE_NUMBER; - } elseif ('varchar' == $attribute->getBackendType() || 'text' == $attribute->getBackendType()) { - return self::FILTER_TYPE_INPUT; - } elseif ($attribute->isStatic()) { + } + + if (isset(self::$backendTypeToFilterMapper[$attribute->getBackendType()])) { + return self::$backendTypeToFilterMapper[$attribute->getBackendType()]; + } + + if ($attribute->isStatic()) { return self::getStaticAttributeFilterType($attribute); - } else { - throw new \Magento\Framework\Exception\LocalizedException( - __('We can\'t determine the attribute filter type.') - ); } + + throw new \Magento\Framework\Exception\LocalizedException( + __('We can\'t determine the attribute filter type.') + ); } /** From 3946034fa9fdb1df5563a99f6d1cc1ea3eee7896 Mon Sep 17 00:00:00 2001 From: Marcin Szterling Date: Thu, 18 Jan 2018 12:56:33 +0000 Subject: [PATCH 012/668] GETWO-1556] Export: Unable to Filter Data by Attribute With Input Type Multiple Select - fixed PHPCS --- app/code/Magento/ImportExport/Model/Export.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/ImportExport/Model/Export.php b/app/code/Magento/ImportExport/Model/Export.php index 11acd68cb1e01..8fa6d0180908d 100644 --- a/app/code/Magento/ImportExport/Model/Export.php +++ b/app/code/Magento/ImportExport/Model/Export.php @@ -93,8 +93,7 @@ public function __construct( \Magento\ImportExport\Model\Export\Entity\Factory $entityFactory, \Magento\ImportExport\Model\Export\Adapter\Factory $exportAdapterFac, array $data = [] - ) - { + ) { $this->_exportConfig = $exportConfig; $this->_entityFactory = $entityFactory; $this->_exportAdapterFac = $exportAdapterFac; From bd8930d35a4588ed2f6ba731eb04af7ebd6067bf Mon Sep 17 00:00:00 2001 From: Marcin Szterling Date: Tue, 30 Jan 2018 09:12:37 +0000 Subject: [PATCH 013/668] GETWO-1556] Export: Unable to Filter Data by Attribute With Input Type Multiple Select Changed variable scope to be protected --- app/code/Magento/ImportExport/Model/Export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ImportExport/Model/Export.php b/app/code/Magento/ImportExport/Model/Export.php index 8fa6d0180908d..50a46201e064d 100644 --- a/app/code/Magento/ImportExport/Model/Export.php +++ b/app/code/Magento/ImportExport/Model/Export.php @@ -70,7 +70,7 @@ class Export extends \Magento\ImportExport\Model\AbstractModel /** * @var array */ - public static $backendTypeToFilterMapper = [ + protected static $backendTypeToFilterMapper = [ 'datetime' => self::FILTER_TYPE_DATE, 'decimal' => self::FILTER_TYPE_NUMBER, 'int' => self::FILTER_TYPE_NUMBER, From 4f2887814a76007bfd29f5f1779f4f3f4cd40c0a Mon Sep 17 00:00:00 2001 From: Marcin Szterling Date: Thu, 1 Feb 2018 15:56:14 +0000 Subject: [PATCH 014/668] GETWO-1556] Export: Unable to Filter Data by Attribute With Input Type Multiple Select Changed variable scope to be private --- app/code/Magento/ImportExport/Model/Export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ImportExport/Model/Export.php b/app/code/Magento/ImportExport/Model/Export.php index 50a46201e064d..695df18fd1030 100644 --- a/app/code/Magento/ImportExport/Model/Export.php +++ b/app/code/Magento/ImportExport/Model/Export.php @@ -70,7 +70,7 @@ class Export extends \Magento\ImportExport\Model\AbstractModel /** * @var array */ - protected static $backendTypeToFilterMapper = [ + private static $backendTypeToFilterMapper = [ 'datetime' => self::FILTER_TYPE_DATE, 'decimal' => self::FILTER_TYPE_NUMBER, 'int' => self::FILTER_TYPE_NUMBER, From 3da3ae662ca23feed8e67c23efbc01230cb7cdd3 Mon Sep 17 00:00:00 2001 From: David Manners Date: Mon, 26 Feb 2018 14:48:36 +0000 Subject: [PATCH 015/668] magento-engcom/import-export-improvements#33: add multi-select attribute filter support for product export - make sure that the abstract entity class knows how to deal with multi select attributes - add finset attribute filter when type matches \Magento\ImportExport\Model\Export::FILTER_TYPE_MULTISELECT --- .../Model/Export/Entity/AbstractEntity.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/code/Magento/ImportExport/Model/Export/Entity/AbstractEntity.php b/app/code/Magento/ImportExport/Model/Export/Entity/AbstractEntity.php index 5cac5e46ffaf0..d9e3879b4be13 100644 --- a/app/code/Magento/ImportExport/Model/Export/Entity/AbstractEntity.php +++ b/app/code/Magento/ImportExport/Model/Export/Entity/AbstractEntity.php @@ -277,6 +277,18 @@ protected function _prepareEntityCollection(\Magento\Eav\Model\Entity\Collection if (is_scalar($exportFilter[$attrCode]) && trim($exportFilter[$attrCode])) { $collection->addAttributeToFilter($attrCode, ['eq' => $exportFilter[$attrCode]]); } + } elseif (\Magento\ImportExport\Model\Export::FILTER_TYPE_MULTISELECT == $attrFilterType) { + if (is_array($exportFilter[$attrCode])) { + array_filter($exportFilter[$attrCode]); + if (!empty($exportFilter[$attrCode])) { + foreach ($exportFilter[$attrCode] as $val) { + $collection->addAttributeToFilter( + $attrCode, + ['finset' => $val] + ); + } + } + } } elseif (\Magento\ImportExport\Model\Export::FILTER_TYPE_INPUT == $attrFilterType) { if (is_scalar($exportFilter[$attrCode]) && trim($exportFilter[$attrCode])) { $collection->addAttributeToFilter($attrCode, ['like' => "%{$exportFilter[$attrCode]}%"]); From b5d43e45c3a5a30cd7f8f6d30ecb62951a20be1f Mon Sep 17 00:00:00 2001 From: John Stennett Date: Mon, 29 Jan 2018 18:25:01 -0600 Subject: [PATCH 016/668] MQE-727: MSI Test Cases - Automating Test Case #1408726 - Simple Product created with Default Source assigned by Admin user - Replacing "steps verbose" with "debug" in the group robo command. Debug contains everything. --- dev/tests/acceptance/RoboFile.php | 2 +- .../Section/AdminProductFormSection.xml | 31 ++++++++ .../MultiSourceInventory/Test/MSICest.xml | 70 +++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminProductFormSection.xml create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/MSICest.xml diff --git a/dev/tests/acceptance/RoboFile.php b/dev/tests/acceptance/RoboFile.php index 51fe3e546a0be..b6e9714bb8f39 100644 --- a/dev/tests/acceptance/RoboFile.php +++ b/dev/tests/acceptance/RoboFile.php @@ -89,7 +89,7 @@ function functional() */ function group($args = '') { - $this->taskExec('.' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'codecept run functional --verbose --steps --skip-group skip --group')->args($args)->run(); + $this->taskExec('.' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'codecept run functional --debug --skip-group skip --group')->args($args)->run(); } /** diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminProductFormSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminProductFormSection.xml new file mode 100644 index 0000000000000..59f604f428fac --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminProductFormSection.xml @@ -0,0 +1,31 @@ + + + + +
+ +
+
+ + + + + + + + + + +
+
+ + + +
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/MSICest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/MSICest.xml new file mode 100644 index 0000000000000..31ae094c19257 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/MSICest.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From a9877cf7393e0d109ba9a1a153eb56e1c6642425 Mon Sep 17 00:00:00 2001 From: John Stennett Date: Tue, 30 Jan 2018 14:50:55 -0600 Subject: [PATCH 017/668] MQE-727: MSI Test Cases - Adding the MsiProductData and MsiSourceData files. - Adding the ManageSourcesPage. - Adding MSI Section files. - Adding a new Create New Source Test. - Renaming MSITest to be more specific. --- .../Data/MsiProductData.xml | 21 ++++++ .../Data/MsiSourceData.xml | 42 ++++++++++++ .../Page/AdminManageSourcesPage.xml | 16 +++++ .../Section/AdminManageSourcesGridSection.xml | 21 ++++++ .../Section/AdminManageSourcesSection.xml | 46 +++++++++++++ .../Section/AdminProductFormSection.xml | 14 ++-- .../Test/AdminCreateNewSourceCest.xml | 68 +++++++++++++++++++ ...ateSimpleProductWithDefaultSourceCest.xml} | 52 +++++++------- 8 files changed, 248 insertions(+), 32 deletions(-) create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiProductData.xml create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Page/AdminManageSourcesPage.xml create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesGridSection.xml create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesSection.xml create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceCest.xml rename dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/{MSICest.xml => AdminCreateSimpleProductWithDefaultSourceCest.xml} (51%) diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiProductData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiProductData.xml new file mode 100644 index 0000000000000..38019e2ba6bdd --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiProductData.xml @@ -0,0 +1,21 @@ + + + + + + Simple Product 1 + SimpleProduct1 + 10.00 + 100 + 1 + simpleproduct1 + In Stock + 1 + + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml new file mode 100644 index 0000000000000..22c1abe188611 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml @@ -0,0 +1,42 @@ + + + + + + Default Source + default + true + Default Source + 0 + 0 + 0 + + + Test Source 1 + test_source_ + true + Test Source 1 + 0 + 0 + 0 + + First Last + test@test.com + 123-456-7890 + 123-456-7890 + + United States + California + Culver City + 6161 West Centinela Avenue + 90230 + + true + + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Page/AdminManageSourcesPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Page/AdminManageSourcesPage.xml new file mode 100644 index 0000000000000..50b509a25dcb6 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Page/AdminManageSourcesPage.xml @@ -0,0 +1,16 @@ + + + + + +
+
+
+ + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesGridSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesGridSection.xml new file mode 100644 index 0000000000000..f0b8973a76954 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesGridSection.xml @@ -0,0 +1,21 @@ + + + + +
+ + + + +
+
+ + +
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesSection.xml new file mode 100644 index 0000000000000..6dcc45b44a71a --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesSection.xml @@ -0,0 +1,46 @@ + + + + +
+ + + + + + + +
+
+ + + + + + + +
+
+ + + + + + + + + +
+
+ + + + +
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminProductFormSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminProductFormSection.xml index 59f604f428fac..14b363b27bc23 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminProductFormSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminProductFormSection.xml @@ -15,13 +15,13 @@ - - - - - - - + + + + + + +
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceCest.xml new file mode 100644 index 0000000000000..5e06eb5efbe8d --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceCest.xml @@ -0,0 +1,68 @@ + + + + + + + + + + <description value="You should be able to create a New Source, via the Admin."/> + <testCaseId value="1408723"/> + <group value="msi"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <actionGroup ref="logout" stepKey="logoutOfAdmin"/> + </after> + + <amOnPage url="{{ManageSources.url}}" stepKey="amOnTheSourcesListPage"/> + <click selector="{{AdminManageSourcesGrid.addNewSource}}" stepKey="clickOnAddNewSource"/> + + <fillField userInput="{{TestSource.name}}" selector="{{AdminEditSourceGeneralSection.name}}" stepKey="fillNameField1"/> + <fillField userInput="{{TestSource.code}}" selector="{{AdminEditSourceGeneralSection.code}}" stepKey="fillCodeField1"/> + <checkOption selector="{{AdminEditSourceGeneralSection.isEnabled}}" stepKey="checkIsEnabled"/> + <fillField userInput="{{TestSource.description}}" selector="{{AdminEditSourceGeneralSection.description}}" stepKey="fillDescriptionField1"/> + + <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> + <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.latitude}}" stepKey="fillLatitudeField1"/> + <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.longitude}}" stepKey="fillLongitudeField1"/> + <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.priority}}" stepKey="fillPriorityField1"/> + + <conditionalClick selector="{{AdminEditSourceContactInfoSection.closed}}" dependentSelector="{{AdminEditSourceContactInfoSection.opened}}" visible="false" stepKey="clickOnContactInfo1"/> + <fillField userInput="{{TestSource.contactName}}" selector="{{AdminEditSourceContactInfoSection.contactName}}" stepKey="fillContactNameField1"/> + <fillField userInput="{{TestSource.email}}" selector="{{AdminEditSourceContactInfoSection.email}}" stepKey="fillEmailField1"/> + <fillField userInput="{{TestSource.phone}}" selector="{{AdminEditSourceContactInfoSection.phone}}" stepKey="fillPhoneField1"/> + <fillField userInput="{{TestSource.fax}}" selector="{{AdminEditSourceContactInfoSection.fax}}" stepKey="fillFaxField1"/> + + <conditionalClick selector="{{AdminEditSourceAddressDataSection.closed}}" dependentSelector="{{AdminEditSourceAddressDataSection.opened}}" visible="false" stepKey="clickOnAddresses1"/> + <selectOption userInput="{{TestSource.country}}" selector="{{AdminEditSourceAddressDataSection.country}}" stepKey="selectCountry1"/> + <selectOption userInput="{{TestSource.stateProvince}}" selector="{{AdminEditSourceAddressDataSection.state}}" stepKey="selectState1"/> + <fillField userInput="{{TestSource.city}}" selector="{{AdminEditSourceAddressDataSection.city}}" stepKey="fillCityField1"/> + <fillField userInput="{{TestSource.street}}" selector="{{AdminEditSourceAddressDataSection.street}}" stepKey="fillStreetField1"/> + <fillField userInput="{{TestSource.postcode}}" selector="{{AdminEditSourceAddressDataSection.postcode}}" stepKey="fillPostcodeField1"/> + + <conditionalClick selector="{{AdminEditSourceCarriersSection.closed}}" dependentSelector="{{AdminEditSourceCarriersSection.opened}}" visible="false" stepKey="clickOnCarriers1"/> + <checkOption selector="{{AdminEditSourceCarriersSection.useGlobalShippingConfiguration}}" stepKey="checkUseGlobalShippingConfiguration1"/> + <click selector="{{AdminProductFormActionSection.saveArrow}}" stepKey="clickOnSaveArrow1"/> + <click selector="{{AdminProductFormActionSection.saveAndClose}}" stepKey="clickOnSaveAndClose"/> + + <click selector="{{AdminManageSourcesGrid.filters}}" stepKey="clickOnFilters1"/> + <fillField userInput="{{TestSource.code}}" selector="{{AdminManageSourcesFilters.code}}" stepKey="fillCodeField2"/> + <click selector="{{AdminManageSourcesFilters.applyFilters}}" stepKey="clickOnApplyFilters1"/> + + <see userInput="{{TestSource.code}}" selector="{{AdminManageSourcesGrid.rowOne}}" stepKey="seeCodeInRow1"/> + <see userInput="{{TestSource.name}}" selector="{{AdminManageSourcesGrid.rowOne}}" stepKey="seeNameInRow1"/> + <see userInput="Enabled" selector="{{AdminManageSourcesGrid.rowOne}}" stepKey="seeIsEnabledInRow1"/> + <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> + <see userInput="0" selector="{{AdminManageSourcesGrid.rowOne}}" stepKey="seePriorityInRow1"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/MSICest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceCest.xml similarity index 51% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/MSICest.xml rename to dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceCest.xml index 31ae094c19257..66ba55d077e39 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/MSICest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceCest.xml @@ -8,10 +8,14 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="RandomMsiTest"> + <test name="AdminCreateSimpleProductWithDefaultSourceTest"> <annotations> - <group value="banana"/> + <features value="Multi-Source Inventory"/> + <stories value="Assign Default Source to New Product"/> + <title value="Simple Product created with Default Source assigned by Admin user"/> + <description value="You should be able to create a New Product, via the Admin, and assign the Default Source to it."/> <testCaseId value="1408726"/> + <group value="msi"/> </annotations> <before> <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> @@ -20,11 +24,12 @@ <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> <click selector="{{AdminProductGridActionSection.addProductToggle}}" stepKey="clickAddProductDropdown"/> <click selector="{{AdminProductGridActionSection.addSimpleProduct}}" stepKey="clickAddSimpleProduct"/> - <fillField userInput="{{_defaultProduct.name}}" selector="{{AdminProductFormSection.productName}}" stepKey="fillName"/> - <fillField userInput="{{_defaultProduct.sku}}" selector="{{AdminProductFormSection.productSku}}" stepKey="fillSKU"/> - <fillField userInput="{{_defaultProduct.price}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="fillPrice"/> - <searchAndMultiSelectOption selector="{{AdminProductFormSection.categoriesDropdown}}" parameterArray="[$$createPreReqCategory.name$$]" stepKey="searchAndSelectCategory"/> - <click selector="button[data-action='close-advanced-select']" stepKey="clickOnDone"/> + <fillField userInput="{{SimpleMsiProduct.name}}" selector="{{AdminProductFormSection.productName}}" stepKey="fillName"/> + <fillField userInput="{{SimpleMsiProduct.sku}}" selector="{{AdminProductFormSection.productSku}}" stepKey="fillSKU"/> + <fillField userInput="{{SimpleMsiProduct.price}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="fillPrice"/> + <searchAndMultiSelectOption selector="{{AdminProductFormSection.categoriesDropdown}}" parameterArray="[$$createPreReqCategory.name$$]" requiredAction="true" stepKey="searchAndSelectCategory"/> + <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSeoSection"/> + <fillField userInput="{{SimpleMsiProduct.urlKey}}" selector="{{AdminProductSEOSection.urlKeyInput}}" stepKey="fillUrlKey"/> <waitForPageLoad stepKey="waitForPageLoad"/> </before> <after> @@ -37,34 +42,31 @@ <click selector="{{AdminProductSourcesSidebarSection.defaultSourceCheckbox}}" stepKey="clickOnDefaultSource"/> <click selector="{{AdminProductSourcesSidebarSection.done}}" stepKey="clickOnDone"/> - <fillField selector="{{AdminProductSourcesGrid.rowQty}}" userInput="10" stepKey="fillQtyField"/> - <fillField selector="{{AdminProductSourcesGrid.rowNotifyQuantity}}" userInput="1" stepKey="fillNotifyQtyField"/> - - <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSeoSection"/> - <fillField userInput="{{_defaultProduct.urlKey}}" selector="{{AdminProductSEOSection.urlKeyInput}}" stepKey="fillUrlKey"/> + <fillField selector="{{AdminProductSourcesGrid.rowQty}}" userInput="{{SimpleMsiProduct.quantity}}" stepKey="fillQtyField"/> + <fillField selector="{{AdminProductSourcesGrid.rowNotifyQuantity}}" userInput="{{SimpleMsiProduct.notifyQuantity}}" stepKey="fillNotifyQtyField"/> <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct"/> <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertSaveMessageSuccess"/> - <see selector="{{AdminProductSourcesGrid.rowId}}" userInput="default" stepKey="seeDefaultAsId"/> - <see selector="{{AdminProductSourcesGrid.rowName}}" userInput="Default Source" stepKey="seeDefaultSourceAsName"/> - <seeOptionIsSelected selector="{{AdminProductSourcesGrid.rowStatus}}" userInput="In Stock" stepKey="seeInStock"/> - <seeInField selector="{{AdminProductSourcesGrid.rowQty}}" userInput="10" stepKey="seeQtyInField"/> - <seeInField selector="{{AdminProductSourcesGrid.rowNotifyQuantity}}" userInput="1" stepKey="seeNotifyQtyInField"/> + <see selector="{{AdminProductSourcesGrid.rowId}}" userInput="{{_defaultSource.id}}" stepKey="seeDefaultAsId"/> + <see selector="{{AdminProductSourcesGrid.rowName}}" userInput="{{_defaultSource.name}}" stepKey="seeDefaultSourceAsName"/> + <seeOptionIsSelected selector="{{AdminProductSourcesGrid.rowStatus}}" userInput="{{SimpleMsiProduct.stockStatus}}" stepKey="seeInStock"/> + <seeInField selector="{{AdminProductSourcesGrid.rowQty}}" userInput="{{SimpleMsiProduct.quantity}}" stepKey="seeQtyInField"/> + <seeInField selector="{{AdminProductSourcesGrid.rowNotifyQuantity}}" userInput="{{SimpleMsiProduct.notifyQuantity}}" stepKey="seeNotifyQtyInField"/> <!-- Go to storefront category page, assert product visibility --> <amOnPage url="{{StorefrontCategoryPage.url($$createPreReqCategory.name$$)}}" stepKey="navigateToCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad1"/> - <see userInput="{{_defaultProduct.name}}" stepKey="assertProductPresent"/> - <see userInput="{{_defaultProduct.price}}" stepKey="assertProductPricePresent"/> + <see userInput="{{SimpleMsiProduct.name}}" stepKey="assertProductPresent"/> + <see userInput="{{SimpleMsiProduct.price}}" stepKey="assertProductPricePresent"/> <!-- Go to storefront product page, assert product visibility --> - <amOnPage url="{{_defaultProduct.urlKey}}.html" stepKey="navigateToProductPage"/> + <amOnPage url="{{SimpleMsiProduct.urlKey}}.html" stepKey="navigateToProductPage"/> <waitForPageLoad stepKey="waitForPageLoad2"/> - <seeInTitle userInput="{{_defaultProduct.name}}" stepKey="assertProductNameTitle"/> - <see userInput="{{_defaultProduct.name}}" selector="{{StorefrontProductInfoMainSection.productName}}" stepKey="assertProductName"/> - <see userInput="{{_defaultProduct.price}}" selector="{{StorefrontProductInfoMainSection.productPrice}}" stepKey="assertProductPrice"/> - <see userInput="{{_defaultProduct.sku}}" selector="{{StorefrontProductInfoMainSection.productSku}}" stepKey="assertProductSku"/> - <see userInput="In Stock" selector="{{StorefrontProductInfoMainSection.productStockStatus}}" stepKey="assertProductStockStatus"/> + <seeInTitle userInput="{{SimpleMsiProduct.name}}" stepKey="assertProductNameTitle"/> + <see userInput="{{SimpleMsiProduct.name}}" selector="{{StorefrontProductInfoMainSection.productName}}" stepKey="assertProductName"/> + <see userInput="{{SimpleMsiProduct.price}}" selector="{{StorefrontProductInfoMainSection.productPrice}}" stepKey="assertProductPrice"/> + <see userInput="{{SimpleMsiProduct.sku}}" selector="{{StorefrontProductInfoMainSection.productSku}}" stepKey="assertProductSku"/> + <see userInput="{{SimpleMsiProduct.stockStatus}}" selector="{{StorefrontProductInfoMainSection.productStockStatus}}" stepKey="assertProductStockStatus"/> </test> </tests> From 31fe0e70954b51c5770b6be68313e0a80c092fb4 Mon Sep 17 00:00:00 2001 From: John Stennett <john00ivy@gmail.com> Date: Wed, 31 Jan 2018 10:41:55 -0600 Subject: [PATCH 018/668] MQE-727: MSI Test Cases - Adding a Sections for generic Admin Grid controls (i.e. "Filters", ""Columns", etc). - Adding additional Filter selectors. - Updating selectors in the Test so they use the correct Page Objects. --- .../Section/AdminGridControlsSection.xml | 45 +++++++++++++++++++ .../Section/AdminProductFormActionSection.xml | 2 + .../Section/AdminManageSourcesGridSection.xml | 7 --- .../Test/AdminCreateNewSourceCest.xml | 14 +++--- 4 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridControlsSection.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridControlsSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridControlsSection.xml new file mode 100644 index 0000000000000..b5b346484e1c0 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridControlsSection.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminGridFilterControls"> + <element name="filters" type="button" selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] button[data-action='grid-filter-expand']"/> + <element name="applyFilters" type="button" selector="button[data-action='grid-filter-apply']" timeout="30"/> + + <!-- Manage Sources Filters --> + <element name="code" type="input" selector=".admin__data-grid-filters-wrap input[name='source_code']"/> + <element name="name" type="input" selector=".admin__data-grid-filters-wrap input[name='name']"/> + <element name="priority" type="input" selector=".admin__data-grid-filters-wrap input[name='priority']"/> + </section> + <section name="AdminGridColumnsControls"> + <element name="columns" type="button" selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .admin__data-grid-action-columns"/> + + <!-- Manage Sources Column Names --> + <element name="code" type="text" selector="//label[contains(text(), 'Code')]"/> + <element name="isEnabled" type="text" selector="//label[contains(text(), 'Is Enabled')]"/> + <element name="longitude" type="text" selector="//label[contains(text(), 'Longitude')]"/> + <element name="stateProvince" type="text" selector="(//label[contains(text(), 'StateProvince')])[1]"/> + <element name="postcode" type="text" selector="//label[contains(text(), 'Postcode')]"/> + <element name="priority" type="text" selector="//label[contains(text(), 'Priority')]"/> + <element name="name" type="text" selector="//label[contains(text(), 'Name')]"/> + <element name="email" type="text" selector="//label[contains(text(), 'Email')]"/> + <element name="country" type="text" selector="//label[contains(text(), 'Country')]"/> + <element name="city" type="text" selector="//label[contains(text(), 'City')]"/> + <element name="phone" type="text" selector="//label[contains(text(), 'Phone')]"/> + <element name="action" type="text" selector="//label[contains(text(), 'Action')]"/> + <element name="contactName" type="text" selector="//label[contains(text(), 'Contact Name')]"/> + <element name="latitude" type="text" selector="//label[contains(text(), 'Latitude')]"/> + <element name="stateProvince" type="text" selector="(//label[contains(text(), 'StateProvince')])[2]"/> + <element name="street" type="text" selector="//label[contains(text(), 'Street')]"/> + <element name="fax" type="text" selector="//label[contains(text(), 'Fax')]"/> + </section> + <section name="AdminGrid"> + <element name="rowOne" type="text" selector="tr[data-repeat-index='0']"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFormActionSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFormActionSection.xml index 427c3523bb002..8c9789d3a6a48 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFormActionSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFormActionSection.xml @@ -11,5 +11,7 @@ <section name="AdminProductFormActionSection"> <element name="backButton" type="button" selector="#back" timeout="30"/> <element name="saveButton" type="button" selector="#save-button" timeout="30"/> + <element name="saveArrow" type="button" selector="button[data-ui-id='save-button-dropdown']" timeout="10"/> + <element name="saveAndClose" type="button" selector="span[title='Save & Close']" timeout="30"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesGridSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesGridSection.xml index f0b8973a76954..c527b9096485b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesGridSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesGridSection.xml @@ -10,12 +10,5 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="AdminManageSourcesGrid"> <element name="addNewSource" type="button" selector="#add" timeout="30"/> - <element name="filters" type="button" selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] button[data-action='grid-filter-expand']"/> - - <element name="rowOne" type="text" selector="tr[data-repeat-index='0']"/> - </section> - <section name="AdminManageSourcesFilters"> - <element name="code" type="input" selector=".admin__data-grid-filters-wrap input[name='source_code']"/> - <element name="applyFilters" type="button" selector="button[data-action='grid-filter-apply']" timeout="30"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceCest.xml index 5e06eb5efbe8d..bea751dbed8d6 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceCest.xml @@ -55,14 +55,14 @@ <click selector="{{AdminProductFormActionSection.saveArrow}}" stepKey="clickOnSaveArrow1"/> <click selector="{{AdminProductFormActionSection.saveAndClose}}" stepKey="clickOnSaveAndClose"/> - <click selector="{{AdminManageSourcesGrid.filters}}" stepKey="clickOnFilters1"/> - <fillField userInput="{{TestSource.code}}" selector="{{AdminManageSourcesFilters.code}}" stepKey="fillCodeField2"/> - <click selector="{{AdminManageSourcesFilters.applyFilters}}" stepKey="clickOnApplyFilters1"/> + <click selector="{{AdminGridFilterControls.filters}}" stepKey="clickOnFilters1"/> + <fillField userInput="{{TestSource.code}}" selector="{{AdminGridFilterControls.code}}" stepKey="fillCodeField2"/> + <click selector="{{AdminGridFilterControls.applyFilters}}" stepKey="clickOnApplyFilters1"/> - <see userInput="{{TestSource.code}}" selector="{{AdminManageSourcesGrid.rowOne}}" stepKey="seeCodeInRow1"/> - <see userInput="{{TestSource.name}}" selector="{{AdminManageSourcesGrid.rowOne}}" stepKey="seeNameInRow1"/> - <see userInput="Enabled" selector="{{AdminManageSourcesGrid.rowOne}}" stepKey="seeIsEnabledInRow1"/> + <see userInput="{{TestSource.code}}" selector="{{AdminGrid.rowOne}}" stepKey="seeCodeInRow1"/> + <see userInput="{{TestSource.name}}" selector="{{AdminGrid.rowOne}}" stepKey="seeNameInRow1"/> + <see userInput="Enabled" selector="{{AdminGrid.rowOne}}" stepKey="seeIsEnabledInRow1"/> <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> - <see userInput="0" selector="{{AdminManageSourcesGrid.rowOne}}" stepKey="seePriorityInRow1"/> + <see userInput="0" selector="{{AdminGrid.rowOne}}" stepKey="seePriorityInRow1"/> </test> </tests> From e2326fca99ac4c68c8cc0971c9614918dbb40f0b Mon Sep 17 00:00:00 2001 From: John Stennett <john00ivy@gmail.com> Date: Thu, 1 Feb 2018 15:04:28 -0600 Subject: [PATCH 019/668] MQE-727: MSI Test Cases - Adding an Update Source Test. - Updating Data names. Adding new data sets. --- .../Data/MsiSourceData.xml | 57 ++++++++++- ...eCest.xml => AdminCreateNewSourceTest.xml} | 32 +++---- ...ateSimpleProductWithDefaultSourceTest.xml} | 2 +- .../Test/AdminUpdateSourceDataTest.xml | 95 +++++++++++++++++++ 4 files changed, 164 insertions(+), 22 deletions(-) rename dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/{AdminCreateNewSourceCest.xml => AdminCreateNewSourceTest.xml} (58%) rename dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/{AdminCreateSimpleProductWithDefaultSourceCest.xml => AdminCreateSimpleProductWithDefaultSourceTest.xml} (98%) create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminUpdateSourceDataTest.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml index 22c1abe188611..5ae20f38acef4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml @@ -8,35 +8,82 @@ <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="_defaultSource" type="Source"> + <entity name="minimal" type="general"> + <data key="id_field_name">null</data> + <data key="name" unique="suffix">Default Source </data> + <data key="source_code" unique="suffix">minimal_</data> + <data key="enabled">1</data> + <data key="country_id">US</data> + <data key="postcode">90230</data> + <data key="use_default_carrier_config">1</data> + </entity> + <entity name="_defaultSource" type="general"> + <data key="id_field_name">source_code</data> <data key="name">Default Source</data> - <data key="id">default</data> + <data key="source_code" unique="suffix">default</data> + <data key="enabled">1</data> <data key="isEnabled">true</data> <data key="description">Default Source</data> <data key="latitude">0</data> <data key="longitude">0</data> <data key="priority">0</data> + <data key="country_id">US</data> + <data key="region_id">12</data> + <data key="postcode">90230</data> + <data key="use_default_carrier_config">1</data> </entity> - <entity name="TestSource" type="Source"> + <entity name="TestSource1" type="general"> + <data key="id_field_name">source_code</data> <data key="name">Test Source 1</data> - <data key="code" unique="suffix">test_source_</data> + <data key="source_code" unique="suffix">test_source_1_</data> <data key="isEnabled">true</data> + <data key="enabled">1</data> <data key="description">Test Source 1</data> <data key="latitude">0</data> <data key="longitude">0</data> <data key="priority">0</data> - <data key="contactName">First Last</data> + <data key="contact_name">First Last</data> <data key="email" unique="prefix">test@test.com</data> <data key="phone">123-456-7890</data> <data key="fax">123-456-7890</data> <data key="country">United States</data> + <data key="country_id">US</data> <data key="stateProvince">California</data> + <data key="region_id">12</data> + <data key="city">Culver City</data> + <data key="street">6161 West Centinela Avenue</data> + <data key="postcode">90230</data> + + <data key="useGlobalShippingConfiguration">true</data> + <data key="use_default_carrier_config">1</data> + </entity> + <entity name="TestSource2" type="general"> + <data key="id_field_name">new_source_code</data> + <data key="name">Test Source 2</data> + <data key="source_code" unique="suffix">test_source_2_</data> + <data key="isEnabled">true</data> + <data key="enabled">1</data> + <data key="description">Test Source 1</data> + <data key="latitude">0</data> + <data key="longitude">0</data> + <data key="priority">0</data> + + <data key="contact_name">New First New Last</data> + <data key="email" unique="prefix">new@test.com</data> + <data key="phone">987-654-3210</data> + <data key="fax">987-654-3210</data> + + <data key="country">Canada</data> + <data key="country_id">CA</data> + <data key="stateProvince">Quebec</data> + <data key="region_id">76</data> <data key="city">Culver City</data> <data key="street">6161 West Centinela Avenue</data> <data key="postcode">90230</data> <data key="useGlobalShippingConfiguration">true</data> + <data key="use_default_carrier_config">1</data> </entity> </entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceTest.xml similarity index 58% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceCest.xml rename to dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceTest.xml index bea751dbed8d6..3161bd2573a6f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceTest.xml @@ -7,7 +7,7 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminCreateNewSourceTest"> <annotations> <features value="Multi-Store Inventory"/> @@ -27,10 +27,10 @@ <amOnPage url="{{ManageSources.url}}" stepKey="amOnTheSourcesListPage"/> <click selector="{{AdminManageSourcesGrid.addNewSource}}" stepKey="clickOnAddNewSource"/> - <fillField userInput="{{TestSource.name}}" selector="{{AdminEditSourceGeneralSection.name}}" stepKey="fillNameField1"/> - <fillField userInput="{{TestSource.code}}" selector="{{AdminEditSourceGeneralSection.code}}" stepKey="fillCodeField1"/> + <fillField userInput="{{TestSource1.name}}" selector="{{AdminEditSourceGeneralSection.name}}" stepKey="fillNameField1"/> + <fillField userInput="{{TestSource1.source_code}}" selector="{{AdminEditSourceGeneralSection.code}}" stepKey="fillCodeField1"/> <checkOption selector="{{AdminEditSourceGeneralSection.isEnabled}}" stepKey="checkIsEnabled"/> - <fillField userInput="{{TestSource.description}}" selector="{{AdminEditSourceGeneralSection.description}}" stepKey="fillDescriptionField1"/> + <fillField userInput="{{TestSource1.description}}" selector="{{AdminEditSourceGeneralSection.description}}" stepKey="fillDescriptionField1"/> <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.latitude}}" stepKey="fillLatitudeField1"/> @@ -38,17 +38,17 @@ <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.priority}}" stepKey="fillPriorityField1"/> <conditionalClick selector="{{AdminEditSourceContactInfoSection.closed}}" dependentSelector="{{AdminEditSourceContactInfoSection.opened}}" visible="false" stepKey="clickOnContactInfo1"/> - <fillField userInput="{{TestSource.contactName}}" selector="{{AdminEditSourceContactInfoSection.contactName}}" stepKey="fillContactNameField1"/> - <fillField userInput="{{TestSource.email}}" selector="{{AdminEditSourceContactInfoSection.email}}" stepKey="fillEmailField1"/> - <fillField userInput="{{TestSource.phone}}" selector="{{AdminEditSourceContactInfoSection.phone}}" stepKey="fillPhoneField1"/> - <fillField userInput="{{TestSource.fax}}" selector="{{AdminEditSourceContactInfoSection.fax}}" stepKey="fillFaxField1"/> + <fillField userInput="{{TestSource1.contact_name}}" selector="{{AdminEditSourceContactInfoSection.contactName}}" stepKey="fillContactNameField1"/> + <fillField userInput="{{TestSource1.email}}" selector="{{AdminEditSourceContactInfoSection.email}}" stepKey="fillEmailField1"/> + <fillField userInput="{{TestSource1.phone}}" selector="{{AdminEditSourceContactInfoSection.phone}}" stepKey="fillPhoneField1"/> + <fillField userInput="{{TestSource1.fax}}" selector="{{AdminEditSourceContactInfoSection.fax}}" stepKey="fillFaxField1"/> <conditionalClick selector="{{AdminEditSourceAddressDataSection.closed}}" dependentSelector="{{AdminEditSourceAddressDataSection.opened}}" visible="false" stepKey="clickOnAddresses1"/> - <selectOption userInput="{{TestSource.country}}" selector="{{AdminEditSourceAddressDataSection.country}}" stepKey="selectCountry1"/> - <selectOption userInput="{{TestSource.stateProvince}}" selector="{{AdminEditSourceAddressDataSection.state}}" stepKey="selectState1"/> - <fillField userInput="{{TestSource.city}}" selector="{{AdminEditSourceAddressDataSection.city}}" stepKey="fillCityField1"/> - <fillField userInput="{{TestSource.street}}" selector="{{AdminEditSourceAddressDataSection.street}}" stepKey="fillStreetField1"/> - <fillField userInput="{{TestSource.postcode}}" selector="{{AdminEditSourceAddressDataSection.postcode}}" stepKey="fillPostcodeField1"/> + <selectOption userInput="{{TestSource1.country}}" selector="{{AdminEditSourceAddressDataSection.country}}" stepKey="selectCountry1"/> + <selectOption userInput="{{TestSource1.stateProvince}}" selector="{{AdminEditSourceAddressDataSection.state}}" stepKey="selectState1"/> + <fillField userInput="{{TestSource1.city}}" selector="{{AdminEditSourceAddressDataSection.city}}" stepKey="fillCityField1"/> + <fillField userInput="{{TestSource1.street}}" selector="{{AdminEditSourceAddressDataSection.street}}" stepKey="fillStreetField1"/> + <fillField userInput="{{TestSource1.postcode}}" selector="{{AdminEditSourceAddressDataSection.postcode}}" stepKey="fillPostcodeField1"/> <conditionalClick selector="{{AdminEditSourceCarriersSection.closed}}" dependentSelector="{{AdminEditSourceCarriersSection.opened}}" visible="false" stepKey="clickOnCarriers1"/> <checkOption selector="{{AdminEditSourceCarriersSection.useGlobalShippingConfiguration}}" stepKey="checkUseGlobalShippingConfiguration1"/> @@ -56,11 +56,11 @@ <click selector="{{AdminProductFormActionSection.saveAndClose}}" stepKey="clickOnSaveAndClose"/> <click selector="{{AdminGridFilterControls.filters}}" stepKey="clickOnFilters1"/> - <fillField userInput="{{TestSource.code}}" selector="{{AdminGridFilterControls.code}}" stepKey="fillCodeField2"/> + <fillField userInput="{{TestSource1.source_code}}" selector="{{AdminGridFilterControls.code}}" stepKey="fillCodeField2"/> <click selector="{{AdminGridFilterControls.applyFilters}}" stepKey="clickOnApplyFilters1"/> - <see userInput="{{TestSource.code}}" selector="{{AdminGrid.rowOne}}" stepKey="seeCodeInRow1"/> - <see userInput="{{TestSource.name}}" selector="{{AdminGrid.rowOne}}" stepKey="seeNameInRow1"/> + <see userInput="{{TestSource1.source_code}}" selector="{{AdminGrid.rowOne}}" stepKey="seeCodeInRow1"/> + <see userInput="{{TestSource1.name}}" selector="{{AdminGrid.rowOne}}" stepKey="seeNameInRow1"/> <see userInput="Enabled" selector="{{AdminGrid.rowOne}}" stepKey="seeIsEnabledInRow1"/> <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> <see userInput="0" selector="{{AdminGrid.rowOne}}" stepKey="seePriorityInRow1"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceTest.xml similarity index 98% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceCest.xml rename to dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceTest.xml index 66ba55d077e39..49bcd47cf7fc4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceTest.xml @@ -48,7 +48,7 @@ <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct"/> <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertSaveMessageSuccess"/> - <see selector="{{AdminProductSourcesGrid.rowId}}" userInput="{{_defaultSource.id}}" stepKey="seeDefaultAsId"/> + <see selector="{{AdminProductSourcesGrid.rowId}}" userInput="{{_defaultSource.source_code}}" stepKey="seeDefaultAsId"/> <see selector="{{AdminProductSourcesGrid.rowName}}" userInput="{{_defaultSource.name}}" stepKey="seeDefaultSourceAsName"/> <seeOptionIsSelected selector="{{AdminProductSourcesGrid.rowStatus}}" userInput="{{SimpleMsiProduct.stockStatus}}" stepKey="seeInStock"/> <seeInField selector="{{AdminProductSourcesGrid.rowQty}}" userInput="{{SimpleMsiProduct.quantity}}" stepKey="seeQtyInField"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminUpdateSourceDataTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminUpdateSourceDataTest.xml new file mode 100644 index 0000000000000..2fa0eb738525f --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminUpdateSourceDataTest.xml @@ -0,0 +1,95 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminUpdateSourceDataTest"> + <annotations> + <features value="Multi-Source Inventory"/> + <stories value="Update existing Source Data"/> + <title value="Source data updated by Admin user"/> + <description value="You should be able to update a Sources data via the Admin."/> + <testCaseId value="1408732"/> + <group value="msi"/> + </annotations> + + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <actionGroup ref="logout" stepKey="logoutOfAdmin"/> + </after> + + <amOnPage url="{{ManageSources.url}}" stepKey="amOnTheSourcesListPage1"/> + <click selector="{{AdminManageSourcesGrid.addNewSource}}" stepKey="clickOnAddNewSource1"/> + + <fillField userInput="{{TestSource1.name}}" selector="{{AdminEditSourceGeneralSection.name}}" stepKey="fillNameField1"/> + <fillField userInput="{{TestSource1.source_code}}" selector="{{AdminEditSourceGeneralSection.code}}" stepKey="fillCodeField1"/> + <checkOption selector="{{AdminEditSourceGeneralSection.isEnabled}}" stepKey="checkIsEnabled1"/> + <fillField userInput="{{TestSource1.description}}" selector="{{AdminEditSourceGeneralSection.description}}" stepKey="fillDescriptionField1"/> + + <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> + <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.latitude}}" stepKey="fillLatitudeField1"/> + <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.longitude}}" stepKey="fillLongitudeField1"/> + <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.priority}}" stepKey="fillPriorityField1"/> + + <conditionalClick selector="{{AdminEditSourceContactInfoSection.closed}}" dependentSelector="{{AdminEditSourceContactInfoSection.opened}}" visible="false" stepKey="clickOnContactInfo1"/> + <fillField userInput="{{TestSource1.contact_name}}" selector="{{AdminEditSourceContactInfoSection.contactName}}" stepKey="fillContactNameField1"/> + <fillField userInput="{{TestSource1.email}}" selector="{{AdminEditSourceContactInfoSection.email}}" stepKey="fillEmailField1"/> + <fillField userInput="{{TestSource1.phone}}" selector="{{AdminEditSourceContactInfoSection.phone}}" stepKey="fillPhoneField1"/> + <fillField userInput="{{TestSource1.fax}}" selector="{{AdminEditSourceContactInfoSection.fax}}" stepKey="fillFaxField1"/> + + <conditionalClick selector="{{AdminEditSourceAddressDataSection.closed}}" dependentSelector="{{AdminEditSourceAddressDataSection.opened}}" visible="false" stepKey="clickOnAddresses1"/> + <selectOption userInput="{{TestSource1.country}}" selector="{{AdminEditSourceAddressDataSection.country}}" stepKey="selectCountry1"/> + <selectOption userInput="{{TestSource1.stateProvince}}" selector="{{AdminEditSourceAddressDataSection.state}}" stepKey="selectState1"/> + <fillField userInput="{{TestSource1.city}}" selector="{{AdminEditSourceAddressDataSection.city}}" stepKey="fillCityField1"/> + <fillField userInput="{{TestSource1.street}}" selector="{{AdminEditSourceAddressDataSection.street}}" stepKey="fillStreetField1"/> + <fillField userInput="{{TestSource1.postcode}}" selector="{{AdminEditSourceAddressDataSection.postcode}}" stepKey="fillPostcodeField1"/> + + <conditionalClick selector="{{AdminEditSourceCarriersSection.closed}}" dependentSelector="{{AdminEditSourceCarriersSection.opened}}" visible="false" stepKey="clickOnCarriers1"/> + <checkOption selector="{{AdminEditSourceCarriersSection.useGlobalShippingConfiguration}}" stepKey="checkUseGlobalShippingConfiguration1"/> + + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickOnSaveContinue1"/> + + <fillField userInput="{{TestSource2.name}}" selector="{{AdminEditSourceGeneralSection.name}}" stepKey="fillNameField2"/> + <fillField userInput="{{TestSource2.source_code}}" selector="{{AdminEditSourceGeneralSection.code}}" stepKey="fillCodeField2"/> + <checkOption selector="{{AdminEditSourceGeneralSection.isEnabled}}" stepKey="checkIsEnabled2"/> + <fillField userInput="{{TestSource2.description}}" selector="{{AdminEditSourceGeneralSection.description}}" stepKey="fillDescriptionField2"/> + + <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> + <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.latitude}}" stepKey="fillLatitudeField2"/> + <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.longitude}}" stepKey="fillLongitudeField2"/> + <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.priority}}" stepKey="fillPriorityField2"/> + + <conditionalClick selector="{{AdminEditSourceContactInfoSection.closed}}" dependentSelector="{{AdminEditSourceContactInfoSection.opened}}" visible="false" stepKey="clickOnContactInfo2"/> + <fillField userInput="{{TestSource2.contact_name}}" selector="{{AdminEditSourceContactInfoSection.contactName}}" stepKey="fillContactNameField2"/> + <fillField userInput="{{TestSource2.email}}" selector="{{AdminEditSourceContactInfoSection.email}}" stepKey="fillEmailField2"/> + <fillField userInput="{{TestSource2.phone}}" selector="{{AdminEditSourceContactInfoSection.phone}}" stepKey="fillPhoneField2"/> + <fillField userInput="{{TestSource2.fax}}" selector="{{AdminEditSourceContactInfoSection.fax}}" stepKey="fillFaxField2"/> + + <conditionalClick selector="{{AdminEditSourceAddressDataSection.closed}}" dependentSelector="{{AdminEditSourceAddressDataSection.opened}}" visible="false" stepKey="clickOnAddresses2"/> + <selectOption userInput="{{TestSource2.country}}" selector="{{AdminEditSourceAddressDataSection.country}}" stepKey="selectCountry2"/> + <selectOption userInput="{{TestSource2.stateProvince}}" selector="{{AdminEditSourceAddressDataSection.state}}" stepKey="selectState2"/> + <fillField userInput="{{TestSource2.city}}" selector="{{AdminEditSourceAddressDataSection.city}}" stepKey="fillCityField2"/> + <fillField userInput="{{TestSource2.street}}" selector="{{AdminEditSourceAddressDataSection.street}}" stepKey="fillStreetField2"/> + <fillField userInput="{{TestSource2.postcode}}" selector="{{AdminEditSourceAddressDataSection.postcode}}" stepKey="fillPostcodeField2"/> + + <click selector="{{AdminProductFormActionSection.saveArrow}}" stepKey="clickOnSaveArrow2"/> + <click selector="{{AdminProductFormActionSection.saveAndClose}}" stepKey="clickOnSaveAndClose2"/> + + <click selector="{{AdminGridFilterControls.filters}}" stepKey="clickOnFilters2"/> + <fillField userInput="{{TestSource2.source_code}}" selector="{{AdminGridFilterControls.code}}" stepKey="fillCodeFieldInGrid2"/> + <click selector="{{AdminGridFilterControls.applyFilters}}" stepKey="clickOnApplyFilters2"/> + + <see userInput="{{TestSource2.source_code}}" selector="{{AdminGrid.rowOne}}" stepKey="seeCodeInRow2"/> + <see userInput="{{TestSource2.name}}" selector="{{AdminGrid.rowOne}}" stepKey="seeNameInRow2"/> + <see userInput="Enabled" selector="{{AdminGrid.rowOne}}" stepKey="seeIsEnabledInRow2"/> + <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> + <see userInput="0" selector="{{AdminGrid.rowOne}}" stepKey="seePriorityInRow2"/> + </test> +</tests> From 7066b6a9224485cf095293b440b5ba40c472de4f Mon Sep 17 00:00:00 2001 From: John Stennett <john00ivy@gmail.com> Date: Thu, 1 Feb 2018 15:58:30 -0600 Subject: [PATCH 020/668] MQE-727: MSI Test Cases - Updating Data information. - Adding Source metadata. - Adding filter Sources test. --- .../Data/MsiSourceData.xml | 16 +++---- .../Metadata/source-meta.xml | 37 ++++++++++++++++ .../Test/AdminFilterSourcesInGridTest.xml | 44 +++++++++++++++++++ 3 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Metadata/source-meta.xml create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminFilterSourcesInGridTest.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml index 5ae20f38acef4..9db5f230bac95 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml @@ -19,8 +19,8 @@ </entity> <entity name="_defaultSource" type="general"> <data key="id_field_name">source_code</data> - <data key="name">Default Source</data> - <data key="source_code" unique="suffix">default</data> + <data key="name" unique="suffix">Default Source </data> + <data key="source_code" unique="suffix">default_</data> <data key="enabled">1</data> <data key="isEnabled">true</data> <data key="description">Default Source</data> @@ -34,7 +34,7 @@ </entity> <entity name="TestSource1" type="general"> <data key="id_field_name">source_code</data> - <data key="name">Test Source 1</data> + <data key="name" unique="suffix">Test Source 1 </data> <data key="source_code" unique="suffix">test_source_1_</data> <data key="isEnabled">true</data> <data key="enabled">1</data> @@ -61,11 +61,11 @@ </entity> <entity name="TestSource2" type="general"> <data key="id_field_name">new_source_code</data> - <data key="name">Test Source 2</data> + <data key="name" unique="suffix">Test Source 2 </data> <data key="source_code" unique="suffix">test_source_2_</data> <data key="isEnabled">true</data> <data key="enabled">1</data> - <data key="description">Test Source 1</data> + <data key="description">Test Source 2</data> <data key="latitude">0</data> <data key="longitude">0</data> <data key="priority">0</data> @@ -79,9 +79,9 @@ <data key="country_id">CA</data> <data key="stateProvince">Quebec</data> <data key="region_id">76</data> - <data key="city">Culver City</data> - <data key="street">6161 West Centinela Avenue</data> - <data key="postcode">90230</data> + <data key="city">Québec City</data> + <data key="street">1234 Test Avenue</data> + <data key="postcode">QC G2E 6J5</data> <data key="useGlobalShippingConfiguration">true</data> <data key="use_default_carrier_config">1</data> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Metadata/source-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Metadata/source-meta.xml new file mode 100644 index 0000000000000..473de2954f384 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Metadata/source-meta.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="CreateSource" dataType="general" type="create" + auth="adminFormKey" url="/inventory/source/save" method="POST" successRegex="/messages-message-success/" returnRegex=""> + <contentType>application/x-www-form-urlencoded</contentType> + <object dataType="general" key="general"> + <field key="id_field_name">string</field> + <field key="name">string</field> + <field key="source_code">string</field> + <field key="enabled">boolean</field> + <field key="description">string</field> + <field key="latitude">string</field> + <field key="longitude">string</field> + <field key="priority">integer</field> + <field key="contact_name">string</field> + <field key="email">string</field> + <field key="phone">string</field> + <field key="fax">string</field> + <field key="country_id">string</field> + <field key="region">string</field> + <field key="region_id">integer</field> + <field key="city">string</field> + <field key="street">string</field> + <field key="postcode">string</field> + <field key="use_default_carrier_config">boolean</field> + <field key="carrier_codes">integer</field> + </object> + </operation> +</operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminFilterSourcesInGridTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminFilterSourcesInGridTest.xml new file mode 100644 index 0000000000000..700c066cd9e31 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminFilterSourcesInGridTest.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminFilterSourcesInGridTest"> + <annotations> + <features value="Multi-Store Inventory"/> + <stories value="Filter Sources in Grid"/> + <title value="Filter Sources on the Manage Sources grid"/> + <description value="You should be able to Filter the Sources from the Manage Sources grid."/> + <testCaseId value="1408749"/> + <group value="msi"/> + </annotations> + <before> + <createData entity="TestSource1" stepKey="createStuff1"/> + <createData entity="TestSource2" stepKey="createStuff2"/> + <createData entity="TestSource1" stepKey="createStuff3"/> + <createData entity="TestSource2" stepKey="createStuff4"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <actionGroup ref="logout" stepKey="logoutOfAdmin"/> + </after> + + <amOnPage url="{{ManageSources.url}}" stepKey="amOnTheSourcesListPage"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + + <click selector="{{AdminGridFilterControls.filters}}" stepKey="clickOnFilters1"/> + <fillField userInput="$$createStuff3.general[source_code]$$" selector="{{AdminGridFilterControls.code}}" stepKey="fillCodeField2"/> + <click selector="{{AdminGridFilterControls.applyFilters}}" stepKey="clickOnApplyFilters1"/> + + <see userInput="$$createStuff3.general[source_code]$$" selector="{{AdminGrid.rowOne}}" stepKey="seeCodeInRow1"/> + <see userInput="$$createStuff3.general[name]$$" selector="{{AdminGrid.rowOne}}" stepKey="seeNameInRow1"/> + <see userInput="Enabled" selector="{{AdminGrid.rowOne}}" stepKey="seeIsEnabledInRow1"/> + <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> + <see userInput="0" selector="{{AdminGrid.rowOne}}" stepKey="seePriorityInRow1"/> + </test> +</tests> From 58995c2f121e6268b6d4c61445db84cabfe678a5 Mon Sep 17 00:00:00 2001 From: John Stennett <john00ivy@gmail.com> Date: Mon, 5 Feb 2018 13:11:18 -0600 Subject: [PATCH 021/668] MQE-727: MSI Test Cases - Adding ClearFilterGrid Action Group. - Adding additional Grid selectors. - Updating default data set. - Updating some of the stepKeys so they make more sense. - Updating TestCaseIDs to use ZenHub ID #. - --- .../AdminClearGridFiltersActionGroup.xml | 15 +++++++++ .../Section/AdminGridControlsSection.xml | 14 ++++++++ .../Section/AdminProductFormSection.xml | 1 + .../Data/MsiProductData.xml | 6 ++-- .../Data/MsiSourceData.xml | 26 ++++++--------- .../Test/AdminCreateNewSourceTest.xml | 2 +- ...eateSimpleProductWithDefaultSourceTest.xml | 32 +++++++++++-------- .../Test/AdminFilterSourcesInGridTest.xml | 16 +++++----- .../Test/AdminUpdateSourceDataTest.xml | 2 +- 9 files changed, 72 insertions(+), 42 deletions(-) create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminClearGridFiltersActionGroup.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminClearGridFiltersActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminClearGridFiltersActionGroup.xml new file mode 100644 index 0000000000000..62c3aec2cafea --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminClearGridFiltersActionGroup.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminClearGridFiltersIfPresent"> + <conditionalClick selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .action-remove" dependentSelector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .admin__data-grid-filters-current._show" visible="true" stepKey="clearTheFiltersIfPresent"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridControlsSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridControlsSection.xml index b5b346484e1c0..2a550af13d0df 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridControlsSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridControlsSection.xml @@ -39,7 +39,21 @@ <element name="street" type="text" selector="//label[contains(text(), 'Street')]"/> <element name="fax" type="text" selector="//label[contains(text(), 'Fax')]"/> </section> + <section name="AdminGridSearchBox"> + <element name="searchByKeyword" type="input" selector="#fulltext"/> + <element name="search" type="button" selector="#fulltext + .action-submit"/> + </section> + <section name="AdminActionsMenu"> + <element name="dropDown" type="select" selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .action-select" timeout="30"/> + </section> + <section name="AdminGridRowsPerPage"> + <element name="count" type="select" selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .selectmenu-value input" timeout="30"/> + </section> <section name="AdminGrid"> + <element name="rowByIndex" type="text" selector="tr[data-repeat-index='{{var1}}']" parameterized="true"/> <element name="rowOne" type="text" selector="tr[data-repeat-index='0']"/> + + <element name="checkboxByValue" type="checkbox" selector="//div[@class='data-grid-cell-content'][contains(text(), '{{var1}}')]/parent::*/parent::*/*/*/input" parameterized="true"/> + <element name="checkboxes" type="checkbox" selector=".data-row .admin__control-checkbox"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFormSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFormSection.xml index 1516850c79260..f9d0399ee5037 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFormSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFormSection.xml @@ -12,6 +12,7 @@ <element name="productName" type="input" selector=".admin__field[data-index=name] input"/> <element name="productSku" type="input" selector=".admin__field[data-index=sku] input"/> <element name="productPrice" type="input" selector=".admin__field[data-index=price] input"/> + <element name="productWeight" type="input" selector=".admin__field[data-index=weight] input"/> <element name="categoriesDropdown" type="multiselect" selector="div[data-index='category_ids']"/> <element name="productQuantity" type="input" selector=".admin__field[data-index=qty] input"/> <element name="productStockStatus" type="select" selector="select[name='product[quantity_and_stock_status][is_in_stock]']"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiProductData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiProductData.xml index 38019e2ba6bdd..cc1d81f6e56c4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiProductData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiProductData.xml @@ -9,12 +9,12 @@ <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> <entity name="SimpleMsiProduct" type="product"> - <data key="name" unique="suffix">Simple Product 1</data> - <data key="sku" unique="suffix">SimpleProduct1</data> + <data key="name" unique="suffix">Simple Product </data> + <data key="sku" unique="suffix">Simple_Product_</data> <data key="price">10.00</data> <data key="quantity">100</data> <data key="weight">1</data> - <data key="urlKey" unique="suffix">simpleproduct1</data> + <data key="urlKey" unique="suffix">simple_product_</data> <data key="stockStatus">In Stock</data> <data key="notifyQuantity">1</data> </entity> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml index 9db5f230bac95..27dbf7ac3025b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml @@ -8,15 +8,6 @@ <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="minimal" type="general"> - <data key="id_field_name">null</data> - <data key="name" unique="suffix">Default Source </data> - <data key="source_code" unique="suffix">minimal_</data> - <data key="enabled">1</data> - <data key="country_id">US</data> - <data key="postcode">90230</data> - <data key="use_default_carrier_config">1</data> - </entity> <entity name="_defaultSource" type="general"> <data key="id_field_name">source_code</data> <data key="name" unique="suffix">Default Source </data> @@ -32,6 +23,15 @@ <data key="postcode">90230</data> <data key="use_default_carrier_config">1</data> </entity> + <entity name="_minimalSource" type="general"> + <data key="id_field_name">source_code</data> + <data key="name" unique="suffix">Minimal Source </data> + <data key="source_code" unique="suffix">minimal_source_</data> + <data key="enabled">1</data> + <data key="country_id">US</data> + <data key="postcode">90230</data> + <data key="use_default_carrier_config">1</data> + </entity> <entity name="TestSource1" type="general"> <data key="id_field_name">source_code</data> <data key="name" unique="suffix">Test Source 1 </data> @@ -42,12 +42,10 @@ <data key="latitude">0</data> <data key="longitude">0</data> <data key="priority">0</data> - <data key="contact_name">First Last</data> <data key="email" unique="prefix">test@test.com</data> <data key="phone">123-456-7890</data> <data key="fax">123-456-7890</data> - <data key="country">United States</data> <data key="country_id">US</data> <data key="stateProvince">California</data> @@ -55,12 +53,11 @@ <data key="city">Culver City</data> <data key="street">6161 West Centinela Avenue</data> <data key="postcode">90230</data> - <data key="useGlobalShippingConfiguration">true</data> <data key="use_default_carrier_config">1</data> </entity> <entity name="TestSource2" type="general"> - <data key="id_field_name">new_source_code</data> + <data key="id_field_name">source_code</data> <data key="name" unique="suffix">Test Source 2 </data> <data key="source_code" unique="suffix">test_source_2_</data> <data key="isEnabled">true</data> @@ -69,12 +66,10 @@ <data key="latitude">0</data> <data key="longitude">0</data> <data key="priority">0</data> - <data key="contact_name">New First New Last</data> <data key="email" unique="prefix">new@test.com</data> <data key="phone">987-654-3210</data> <data key="fax">987-654-3210</data> - <data key="country">Canada</data> <data key="country_id">CA</data> <data key="stateProvince">Quebec</data> @@ -82,7 +77,6 @@ <data key="city">Québec City</data> <data key="street">1234 Test Avenue</data> <data key="postcode">QC G2E 6J5</data> - <data key="useGlobalShippingConfiguration">true</data> <data key="use_default_carrier_config">1</data> </entity> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceTest.xml index 3161bd2573a6f..524b4c1910390 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceTest.xml @@ -14,7 +14,7 @@ <stories value="Create New Source"/> <title value="New Source created by Admin user"/> <description value="You should be able to create a New Source, via the Admin."/> - <testCaseId value="1408723"/> + <testCaseId value="482"/> <group value="msi"/> </annotations> <before> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceTest.xml index 49bcd47cf7fc4..745a33b5ef3d3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceTest.xml @@ -14,38 +14,44 @@ <stories value="Assign Default Source to New Product"/> <title value="Simple Product created with Default Source assigned by Admin user"/> <description value="You should be able to create a New Product, via the Admin, and assign the Default Source to it."/> - <testCaseId value="1408726"/> + <testCaseId value="483"/> <group value="msi"/> + <group value="bananas"/> </annotations> <before> <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> - <click selector="{{AdminProductGridActionSection.addProductToggle}}" stepKey="clickAddProductDropdown"/> - <click selector="{{AdminProductGridActionSection.addSimpleProduct}}" stepKey="clickAddSimpleProduct"/> - <fillField userInput="{{SimpleMsiProduct.name}}" selector="{{AdminProductFormSection.productName}}" stepKey="fillName"/> - <fillField userInput="{{SimpleMsiProduct.sku}}" selector="{{AdminProductFormSection.productSku}}" stepKey="fillSKU"/> - <fillField userInput="{{SimpleMsiProduct.price}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="fillPrice"/> - <searchAndMultiSelectOption selector="{{AdminProductFormSection.categoriesDropdown}}" parameterArray="[$$createPreReqCategory.name$$]" requiredAction="true" stepKey="searchAndSelectCategory"/> - <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSeoSection"/> - <fillField userInput="{{SimpleMsiProduct.urlKey}}" selector="{{AdminProductSEOSection.urlKeyInput}}" stepKey="fillUrlKey"/> - <waitForPageLoad stepKey="waitForPageLoad"/> + <waitForPageLoad time="30" stepKey="waitForPageLoad"/> </before> <after> <actionGroup ref="logout" stepKey="logoutOfAdmin"/> <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> </after> + <click selector="{{AdminProductGridActionSection.addProductToggle}}" stepKey="clickAddProductDropdown"/> + <click selector="{{AdminProductGridActionSection.addSimpleProduct}}" stepKey="clickAddSimpleProduct"/> + <fillField userInput="{{SimpleMsiProduct.name}}" selector="{{AdminProductFormSection.productName}}" stepKey="fillName"/> + <fillField userInput="{{SimpleMsiProduct.sku}}" selector="{{AdminProductFormSection.productSku}}" stepKey="fillSKU"/> + <fillField userInput="{{SimpleMsiProduct.price}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="fillPrice"/> + <fillField userInput="{{SimpleMsiProduct.weight}}" selector="{{AdminProductFormSection.productWeight}}" stepKey="fillWeight"/> + <searchAndMultiSelectOption selector="{{AdminProductFormSection.categoriesDropdown}}" parameterArray="[$$createPreReqCategory.name$$]" requiredAction="true" stepKey="searchAndSelectCategory"/> + <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSeoSection"/> + <fillField userInput="{{SimpleMsiProduct.urlKey}}" selector="{{AdminProductSEOSection.urlKeyInput}}" stepKey="fillUrlKey"/> + <waitForPageLoad time="30" stepKey="waitForPageLoad1"/> + <click selector="{{AdminProductSourcesSection.assignSources}}" stepKey="clickOnAssignSource"/> + <actionGroup ref="AdminClearGridFiltersIfPresent" stepKey="clearGridFiltersIfPresent1"/> <click selector="{{AdminProductSourcesSidebarSection.defaultSourceCheckbox}}" stepKey="clickOnDefaultSource"/> <click selector="{{AdminProductSourcesSidebarSection.done}}" stepKey="clickOnDone"/> <fillField selector="{{AdminProductSourcesGrid.rowQty}}" userInput="{{SimpleMsiProduct.quantity}}" stepKey="fillQtyField"/> <fillField selector="{{AdminProductSourcesGrid.rowNotifyQuantity}}" userInput="{{SimpleMsiProduct.notifyQuantity}}" stepKey="fillNotifyQtyField"/> - <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct"/> + <click selector="{{AdminProductFormActionSection.saveArrow}}" stepKey="openSaveDropDown"/> + <click selector="{{AdminProductFormActionSection.saveAndClose}}" stepKey="clickOnSaveAndClose"/> <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertSaveMessageSuccess"/> <see selector="{{AdminProductSourcesGrid.rowId}}" userInput="{{_defaultSource.source_code}}" stepKey="seeDefaultAsId"/> @@ -56,13 +62,13 @@ <!-- Go to storefront category page, assert product visibility --> <amOnPage url="{{StorefrontCategoryPage.url($$createPreReqCategory.name$$)}}" stepKey="navigateToCategoryPage"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> + <waitForPageLoad stepKey="waitForPageLoad3"/> <see userInput="{{SimpleMsiProduct.name}}" stepKey="assertProductPresent"/> <see userInput="{{SimpleMsiProduct.price}}" stepKey="assertProductPricePresent"/> <!-- Go to storefront product page, assert product visibility --> <amOnPage url="{{SimpleMsiProduct.urlKey}}.html" stepKey="navigateToProductPage"/> - <waitForPageLoad stepKey="waitForPageLoad2"/> + <waitForPageLoad stepKey="waitForPageLoad4"/> <seeInTitle userInput="{{SimpleMsiProduct.name}}" stepKey="assertProductNameTitle"/> <see userInput="{{SimpleMsiProduct.name}}" selector="{{StorefrontProductInfoMainSection.productName}}" stepKey="assertProductName"/> <see userInput="{{SimpleMsiProduct.price}}" selector="{{StorefrontProductInfoMainSection.productPrice}}" stepKey="assertProductPrice"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminFilterSourcesInGridTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminFilterSourcesInGridTest.xml index 700c066cd9e31..1d86525a461cd 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminFilterSourcesInGridTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminFilterSourcesInGridTest.xml @@ -14,14 +14,14 @@ <stories value="Filter Sources in Grid"/> <title value="Filter Sources on the Manage Sources grid"/> <description value="You should be able to Filter the Sources from the Manage Sources grid."/> - <testCaseId value="1408749"/> + <testCaseId value="493"/> <group value="msi"/> </annotations> <before> - <createData entity="TestSource1" stepKey="createStuff1"/> - <createData entity="TestSource2" stepKey="createStuff2"/> - <createData entity="TestSource1" stepKey="createStuff3"/> - <createData entity="TestSource2" stepKey="createStuff4"/> + <createData entity="TestSource1" stepKey="createSource1"/> + <createData entity="TestSource2" stepKey="createSource2"/> + <createData entity="TestSource1" stepKey="createSource3"/> + <createData entity="TestSource2" stepKey="createSource4"/> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </before> <after> @@ -32,11 +32,11 @@ <waitForPageLoad stepKey="waitForPageLoad1"/> <click selector="{{AdminGridFilterControls.filters}}" stepKey="clickOnFilters1"/> - <fillField userInput="$$createStuff3.general[source_code]$$" selector="{{AdminGridFilterControls.code}}" stepKey="fillCodeField2"/> + <fillField userInput="$$createSource3.general[source_code]$$" selector="{{AdminGridFilterControls.code}}" stepKey="fillCodeField2"/> <click selector="{{AdminGridFilterControls.applyFilters}}" stepKey="clickOnApplyFilters1"/> - <see userInput="$$createStuff3.general[source_code]$$" selector="{{AdminGrid.rowOne}}" stepKey="seeCodeInRow1"/> - <see userInput="$$createStuff3.general[name]$$" selector="{{AdminGrid.rowOne}}" stepKey="seeNameInRow1"/> + <see userInput="$$createSource3.general[source_code]$$" selector="{{AdminGrid.rowOne}}" stepKey="seeCodeInRow1"/> + <see userInput="$$createSource3.general[name]$$" selector="{{AdminGrid.rowOne}}" stepKey="seeNameInRow1"/> <see userInput="Enabled" selector="{{AdminGrid.rowOne}}" stepKey="seeIsEnabledInRow1"/> <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> <see userInput="0" selector="{{AdminGrid.rowOne}}" stepKey="seePriorityInRow1"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminUpdateSourceDataTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminUpdateSourceDataTest.xml index 2fa0eb738525f..9b83211c031ed 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminUpdateSourceDataTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminUpdateSourceDataTest.xml @@ -14,7 +14,7 @@ <stories value="Update existing Source Data"/> <title value="Source data updated by Admin user"/> <description value="You should be able to update a Sources data via the Admin."/> - <testCaseId value="1408732"/> + <testCaseId value="492"/> <group value="msi"/> </annotations> From 1cd00e9b38fe8925d7771f5d0d948b202bf26195 Mon Sep 17 00:00:00 2001 From: John Stennett <john00ivy@gmail.com> Date: Wed, 7 Feb 2018 15:02:42 -0600 Subject: [PATCH 022/668] MQE-727: MSI Test Cases - Removing the MultiSourceInventory directory. Moved it to the Inventory directory under the MSI repo. - Adding config metadata. - Redid the Admin Grid selectors. --- .../Section/AdminGridControlsSection.xml | 67 ++++++------- .../Section/AdminProductGridSection.xml | 3 + .../Config/Metadata/config-metadata.xml | 21 ++++ .../Data/MsiProductData.xml | 21 ---- .../Data/MsiSourceData.xml | 83 ---------------- .../Metadata/source-meta.xml | 37 -------- .../Page/AdminManageSourcesPage.xml | 16 ---- .../Section/AdminManageSourcesGridSection.xml | 14 --- .../Section/AdminManageSourcesSection.xml | 46 --------- .../Section/AdminProductFormSection.xml | 31 ------ .../Test/AdminCreateNewSourceTest.xml | 68 ------------- ...eateSimpleProductWithDefaultSourceTest.xml | 78 --------------- .../Test/AdminFilterSourcesInGridTest.xml | 44 --------- .../Test/AdminUpdateSourceDataTest.xml | 95 ------------------- 14 files changed, 59 insertions(+), 565 deletions(-) create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/Metadata/config-metadata.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiProductData.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Metadata/source-meta.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Page/AdminManageSourcesPage.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesGridSection.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesSection.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminProductFormSection.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceTest.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceTest.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminFilterSourcesInGridTest.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminUpdateSourceDataTest.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridControlsSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridControlsSection.xml index 2a550af13d0df..3421310210490 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridControlsSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridControlsSection.xml @@ -8,52 +8,55 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminGridHeader"> + <element name="title" type="text" selector=".page-title-wrapper h1"/> + </section> + <!-- TODO: Search, Notifications, Admin Menu --> + <section name="AdminGridMainControls"> + <element name="add" type="button" selector="#add" timeout="30"/> + <element name="back" type="button" selector="#back" timeout="30"/> + <element name="reset" type="button" selector="#reset" timeout="30"/> + <element name="save" type="button" selector="#save-button" timeout="30"/> + <element name="saveAndContinue" type="button" selector="#save-button" timeout="30"/> + <element name="saveArrow" type="button" selector="button[data-ui-id='save-button-dropdown']" timeout="5"/> + <element name="saveAndClose" type="button" selector="span[title='Save & Close']" timeout="30"/> + <element name="saveAndNew" type="button" selector="span[title='Save & New']" timeout="30"/> + </section> + <section name="AdminGridSearchBox"> + <element name="searchByKeyword" type="input" selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] input[placeholder='Search by keyword']"/> + <element name="search" type="button" selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] input[placeholder='Search by keyword'] + .action-submit" timeout="30"/> + </section> <section name="AdminGridFilterControls"> - <element name="filters" type="button" selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] button[data-action='grid-filter-expand']"/> + <element name="filters" type="button" selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] button[data-action='grid-filter-expand']" timeout="5"/> <element name="applyFilters" type="button" selector="button[data-action='grid-filter-apply']" timeout="30"/> - - <!-- Manage Sources Filters --> - <element name="code" type="input" selector=".admin__data-grid-filters-wrap input[name='source_code']"/> - <element name="name" type="input" selector=".admin__data-grid-filters-wrap input[name='name']"/> - <element name="priority" type="input" selector=".admin__data-grid-filters-wrap input[name='priority']"/> + <element name="cancel" type="button" selector="button[data-action='grid-filter-cancel']" timeout="30"/> </section> + <!-- TODO: "Default View" drop down menu --> <section name="AdminGridColumnsControls"> <element name="columns" type="button" selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .admin__data-grid-action-columns"/> - <!-- Manage Sources Column Names --> - <element name="code" type="text" selector="//label[contains(text(), 'Code')]"/> - <element name="isEnabled" type="text" selector="//label[contains(text(), 'Is Enabled')]"/> - <element name="longitude" type="text" selector="//label[contains(text(), 'Longitude')]"/> - <element name="stateProvince" type="text" selector="(//label[contains(text(), 'StateProvince')])[1]"/> - <element name="postcode" type="text" selector="//label[contains(text(), 'Postcode')]"/> - <element name="priority" type="text" selector="//label[contains(text(), 'Priority')]"/> - <element name="name" type="text" selector="//label[contains(text(), 'Name')]"/> - <element name="email" type="text" selector="//label[contains(text(), 'Email')]"/> - <element name="country" type="text" selector="//label[contains(text(), 'Country')]"/> - <element name="city" type="text" selector="//label[contains(text(), 'City')]"/> - <element name="phone" type="text" selector="//label[contains(text(), 'Phone')]"/> - <element name="action" type="text" selector="//label[contains(text(), 'Action')]"/> - <element name="contactName" type="text" selector="//label[contains(text(), 'Contact Name')]"/> - <element name="latitude" type="text" selector="//label[contains(text(), 'Latitude')]"/> - <element name="stateProvince" type="text" selector="(//label[contains(text(), 'StateProvince')])[2]"/> - <element name="street" type="text" selector="//label[contains(text(), 'Street')]"/> - <element name="fax" type="text" selector="//label[contains(text(), 'Fax')]"/> - </section> - <section name="AdminGridSearchBox"> - <element name="searchByKeyword" type="input" selector="#fulltext"/> - <element name="search" type="button" selector="#fulltext + .action-submit"/> + <element name="columnName" type="button" selector="//label[contains(text(), '{{var1}}')]" parameterized="true" timeout="1"/> + + <element name="reset" type="button" selector="//div[@class='admin__action-dropdown-menu-footer']/div/button[contains(text(), 'Reset')]" timeout="5"/> + <element name="cancel" type="button" selector="//div[@class='admin__action-dropdown-menu-footer']/div/button[contains(text(), 'Cancel')]" timeout="5"/> </section> - <section name="AdminActionsMenu"> + <section name="AdminGridActionsMenu"> <element name="dropDown" type="select" selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .action-select" timeout="30"/> </section> <section name="AdminGridRowsPerPage"> <element name="count" type="select" selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .selectmenu-value input" timeout="30"/> </section> - <section name="AdminGrid"> - <element name="rowByIndex" type="text" selector="tr[data-repeat-index='{{var1}}']" parameterized="true"/> + <!-- TODO: Pagination controls --> + <section name="AdminGridHeaders"> + <element name="headerByName" type="text" selector="//span[@class='data-grid-cell-content' and contains(text(), '{{var1}}')]/parent::*" parameterized="true"/> + </section> + <section name="AdminGridRow"> <element name="rowOne" type="text" selector="tr[data-repeat-index='0']"/> + <element name="rowByIndex" type="text" selector="tr[data-repeat-index='{{var1}}']" parameterized="true"/> + + <element name="editByValue" type="button" selector="//div[@class='data-grid-cell-content'][contains(text(), '{{var1}}')]/parent::*/parent::*/*/a" parameterized="true"/> <element name="checkboxByValue" type="checkbox" selector="//div[@class='data-grid-cell-content'][contains(text(), '{{var1}}')]/parent::*/parent::*/*/*/input" parameterized="true"/> - <element name="checkboxes" type="checkbox" selector=".data-row .admin__control-checkbox"/> + <element name="checkboxByIndex" type="checkbox" selector=".data-row[data-repeat-index='{{var1}}'] .admin__control-checkbox" parameterized="true"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductGridSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductGridSection.xml index fc693d6aa1df8..bf2876f56c997 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductGridSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductGridSection.xml @@ -23,4 +23,7 @@ <element name="bulkActionDropdown" type="button" selector="div.admin__data-grid-header-row.row div.action-select-wrap button.action-select"/> <element name="bulkActionOption" type="button" selector="//div[contains(@class,'admin__data-grid-header-row') and contains(@class, 'row')]//div[contains(@class, 'action-select-wrap')]//ul/li/span[text() = '{{label}}']" parameterized="true"/> </section> + <section name="AdminProductGridFilterControls"> + <element name="sku" type="input" selector=".admin__data-grid-filters-wrap input[name='sku']"/> + </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/Metadata/config-metadata.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/Metadata/config-metadata.xml new file mode 100644 index 0000000000000..36eb6a1892e53 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/Metadata/config-metadata.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="UpdateCmsConfiguration" dataType="config_state" type="update" + auth="adminOauth" url="" method=""> + <contentType>application/json</contentType> + <object dataType="config_state" key="config_state"> + <field key="cms_wysiwyg">1</field> + </object> + <object dataType="groups"> + + </object> + </operation> +</operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiProductData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiProductData.xml deleted file mode 100644 index cc1d81f6e56c4..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiProductData.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="SimpleMsiProduct" type="product"> - <data key="name" unique="suffix">Simple Product </data> - <data key="sku" unique="suffix">Simple_Product_</data> - <data key="price">10.00</data> - <data key="quantity">100</data> - <data key="weight">1</data> - <data key="urlKey" unique="suffix">simple_product_</data> - <data key="stockStatus">In Stock</data> - <data key="notifyQuantity">1</data> - </entity> -</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml deleted file mode 100644 index 27dbf7ac3025b..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Data/MsiSourceData.xml +++ /dev/null @@ -1,83 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="_defaultSource" type="general"> - <data key="id_field_name">source_code</data> - <data key="name" unique="suffix">Default Source </data> - <data key="source_code" unique="suffix">default_</data> - <data key="enabled">1</data> - <data key="isEnabled">true</data> - <data key="description">Default Source</data> - <data key="latitude">0</data> - <data key="longitude">0</data> - <data key="priority">0</data> - <data key="country_id">US</data> - <data key="region_id">12</data> - <data key="postcode">90230</data> - <data key="use_default_carrier_config">1</data> - </entity> - <entity name="_minimalSource" type="general"> - <data key="id_field_name">source_code</data> - <data key="name" unique="suffix">Minimal Source </data> - <data key="source_code" unique="suffix">minimal_source_</data> - <data key="enabled">1</data> - <data key="country_id">US</data> - <data key="postcode">90230</data> - <data key="use_default_carrier_config">1</data> - </entity> - <entity name="TestSource1" type="general"> - <data key="id_field_name">source_code</data> - <data key="name" unique="suffix">Test Source 1 </data> - <data key="source_code" unique="suffix">test_source_1_</data> - <data key="isEnabled">true</data> - <data key="enabled">1</data> - <data key="description">Test Source 1</data> - <data key="latitude">0</data> - <data key="longitude">0</data> - <data key="priority">0</data> - <data key="contact_name">First Last</data> - <data key="email" unique="prefix">test@test.com</data> - <data key="phone">123-456-7890</data> - <data key="fax">123-456-7890</data> - <data key="country">United States</data> - <data key="country_id">US</data> - <data key="stateProvince">California</data> - <data key="region_id">12</data> - <data key="city">Culver City</data> - <data key="street">6161 West Centinela Avenue</data> - <data key="postcode">90230</data> - <data key="useGlobalShippingConfiguration">true</data> - <data key="use_default_carrier_config">1</data> - </entity> - <entity name="TestSource2" type="general"> - <data key="id_field_name">source_code</data> - <data key="name" unique="suffix">Test Source 2 </data> - <data key="source_code" unique="suffix">test_source_2_</data> - <data key="isEnabled">true</data> - <data key="enabled">1</data> - <data key="description">Test Source 2</data> - <data key="latitude">0</data> - <data key="longitude">0</data> - <data key="priority">0</data> - <data key="contact_name">New First New Last</data> - <data key="email" unique="prefix">new@test.com</data> - <data key="phone">987-654-3210</data> - <data key="fax">987-654-3210</data> - <data key="country">Canada</data> - <data key="country_id">CA</data> - <data key="stateProvince">Quebec</data> - <data key="region_id">76</data> - <data key="city">Québec City</data> - <data key="street">1234 Test Avenue</data> - <data key="postcode">QC G2E 6J5</data> - <data key="useGlobalShippingConfiguration">true</data> - <data key="use_default_carrier_config">1</data> - </entity> -</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Metadata/source-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Metadata/source-meta.xml deleted file mode 100644 index 473de2954f384..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Metadata/source-meta.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> - <operation name="CreateSource" dataType="general" type="create" - auth="adminFormKey" url="/inventory/source/save" method="POST" successRegex="/messages-message-success/" returnRegex=""> - <contentType>application/x-www-form-urlencoded</contentType> - <object dataType="general" key="general"> - <field key="id_field_name">string</field> - <field key="name">string</field> - <field key="source_code">string</field> - <field key="enabled">boolean</field> - <field key="description">string</field> - <field key="latitude">string</field> - <field key="longitude">string</field> - <field key="priority">integer</field> - <field key="contact_name">string</field> - <field key="email">string</field> - <field key="phone">string</field> - <field key="fax">string</field> - <field key="country_id">string</field> - <field key="region">string</field> - <field key="region_id">integer</field> - <field key="city">string</field> - <field key="street">string</field> - <field key="postcode">string</field> - <field key="use_default_carrier_config">boolean</field> - <field key="carrier_codes">integer</field> - </object> - </operation> -</operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Page/AdminManageSourcesPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Page/AdminManageSourcesPage.xml deleted file mode 100644 index 50b509a25dcb6..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Page/AdminManageSourcesPage.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> - <page name="ManageSources" url="/inventory/source/index/" area="admin" module="MultiSourceInventory"> - <section name="AdminProductSourcesSection"/> - <section name="AdminProductSourcesGrid"/> - <section name="AdminProductSourcesSidebarSection"/> - </page> -</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesGridSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesGridSection.xml deleted file mode 100644 index c527b9096485b..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesGridSection.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - <section name="AdminManageSourcesGrid"> - <element name="addNewSource" type="button" selector="#add" timeout="30"/> - </section> -</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesSection.xml deleted file mode 100644 index 6dcc45b44a71a..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminManageSourcesSection.xml +++ /dev/null @@ -1,46 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - <section name="AdminEditSourceGeneralSection"> - <element name="name" type="input" selector="input[name='general[name]']"/> - <element name="code" type="input" selector="input[name='general[source_code]']"/> - <element name="isEnabled" type="checkbox" selector="input[name='general[enabled]']"/> - <element name="description" type="textarea" selector="textarea[name='general[description]']"/> - <element name="latitude" type="input" selector="input[name='general[latitude]']"/> - <element name="longitude" type="input" selector="input[name='general[longitude]']"/> - <element name="priority" type="input" selector="input[name='general[priority]']"/> - </section> - <section name="AdminEditSourceContactInfoSection"> - <element name="opened" type="wysiwyg" selector="div[data-index='contact_info'] .fieldset-wrapper-title[data-state-collapsible='open']"/> - <element name="closed" type="wysiwyg" selector="div[data-index='contact_info'] .fieldset-wrapper-title[data-state-collapsible='closed']"/> - - <element name="contactName" type="input" selector="input[name='general[contact_name]']"/> - <element name="email" type="input" selector="input[name='general[email]']"/> - <element name="phone" type="input" selector="input[name='general[phone]']"/> - <element name="fax" type="input" selector="input[name='general[fax]']"/> - </section> - <section name="AdminEditSourceAddressDataSection"> - <element name="opened" type="wysiwyg" selector="div[data-index='address'] .fieldset-wrapper-title[data-state-collapsible='open']"/> - <element name="closed" type="wysiwyg" selector="div[data-index='address'] .fieldset-wrapper-title[data-state-collapsible='closed']"/> - - <element name="country" type="select" selector="select[name='general[country_id]']" timeout="10"/> - <element name="province" type="input" selector="input[name='general[region]']"/> - <element name="state" type="select" selector="select[name='general[region_id]']"/> - <element name="city" type="input" selector="input[name='general[city]']"/> - <element name="street" type="input" selector="input[name='general[street]']"/> - <element name="postcode" type="input" selector="input[name='general[postcode]']"/> - </section> - <section name="AdminEditSourceCarriersSection"> - <element name="opened" type="wysiwyg" selector="div[data-index='carriers'] .fieldset-wrapper-title[data-state-collapsible='open']"/> - <element name="closed" type="wysiwyg" selector="div[data-index='carriers'] .fieldset-wrapper-title[data-state-collapsible='closed']"/> - - <element name="useGlobalShippingConfiguration" type="radio" selector="input[name='general[use_default_carrier_config]']"/> - </section> -</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminProductFormSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminProductFormSection.xml deleted file mode 100644 index 14b363b27bc23..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Section/AdminProductFormSection.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - <section name="AdminProductSourcesSection"> - <element name="assignSources" type="button" selector="button[data-index='assign_sources_button']" timeout="30"/> - </section> - <section name="AdminProductSourcesGrid"> - <element name="rowByIndex" type="input" selector="div[data-index='sources'] .data-row[data-repeat-index='{{arg1}}']" parameterized="true"/> - <element name="firstRow" type="input" selector="div[data-index='sources'] .data-row[data-repeat-index='0']"/> - - <element name="rowId" type="button" selector=".data-row[data-repeat-index='0'] span[data-index='source_code']"/> - <element name="rowName" type="button" selector=".data-row[data-repeat-index='0'] span[data-index='name']"/> - <element name="rowStatus" type="button" selector=".data-row[data-repeat-index='0'] select[name='sources[assigned_sources][0][status]']"/> - <element name="rowQty" type="button" selector=".data-row[data-repeat-index='0'] input[name='sources[assigned_sources][0][quantity]']"/> - <element name="rowNotifyQuantity" type="button" selector=".data-row[data-repeat-index='0'] input[name='sources[assigned_sources][0][notify_stock_qty]']"/> - <element name="rowUnAssign" type="button" selector=".data-row[data-repeat-index='0'] button[data-action='remove_row']"/> - <element name="rowNotifyQuantityUseDefault" type="button" selector=".data-row[data-repeat-index='0'] input[name='sources[assigned_sources][0][notify_stock_qty_use_default]']"/> - </section> - <section name="AdminProductSourcesSidebarSection"> - <element name="done" type="button" selector=".product_form_product_form_sources_assign_sources_modal button.action-primary" timeout="30"/> - - <element name="defaultSourceCheckbox" type="checkbox" selector="#idscheckdefault"/> - </section> -</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceTest.xml deleted file mode 100644 index 524b4c1910390..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateNewSourceTest.xml +++ /dev/null @@ -1,68 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="AdminCreateNewSourceTest"> - <annotations> - <features value="Multi-Store Inventory"/> - <stories value="Create New Source"/> - <title value="New Source created by Admin user"/> - <description value="You should be able to create a New Source, via the Admin."/> - <testCaseId value="482"/> - <group value="msi"/> - </annotations> - <before> - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - </before> - <after> - <actionGroup ref="logout" stepKey="logoutOfAdmin"/> - </after> - - <amOnPage url="{{ManageSources.url}}" stepKey="amOnTheSourcesListPage"/> - <click selector="{{AdminManageSourcesGrid.addNewSource}}" stepKey="clickOnAddNewSource"/> - - <fillField userInput="{{TestSource1.name}}" selector="{{AdminEditSourceGeneralSection.name}}" stepKey="fillNameField1"/> - <fillField userInput="{{TestSource1.source_code}}" selector="{{AdminEditSourceGeneralSection.code}}" stepKey="fillCodeField1"/> - <checkOption selector="{{AdminEditSourceGeneralSection.isEnabled}}" stepKey="checkIsEnabled"/> - <fillField userInput="{{TestSource1.description}}" selector="{{AdminEditSourceGeneralSection.description}}" stepKey="fillDescriptionField1"/> - - <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> - <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.latitude}}" stepKey="fillLatitudeField1"/> - <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.longitude}}" stepKey="fillLongitudeField1"/> - <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.priority}}" stepKey="fillPriorityField1"/> - - <conditionalClick selector="{{AdminEditSourceContactInfoSection.closed}}" dependentSelector="{{AdminEditSourceContactInfoSection.opened}}" visible="false" stepKey="clickOnContactInfo1"/> - <fillField userInput="{{TestSource1.contact_name}}" selector="{{AdminEditSourceContactInfoSection.contactName}}" stepKey="fillContactNameField1"/> - <fillField userInput="{{TestSource1.email}}" selector="{{AdminEditSourceContactInfoSection.email}}" stepKey="fillEmailField1"/> - <fillField userInput="{{TestSource1.phone}}" selector="{{AdminEditSourceContactInfoSection.phone}}" stepKey="fillPhoneField1"/> - <fillField userInput="{{TestSource1.fax}}" selector="{{AdminEditSourceContactInfoSection.fax}}" stepKey="fillFaxField1"/> - - <conditionalClick selector="{{AdminEditSourceAddressDataSection.closed}}" dependentSelector="{{AdminEditSourceAddressDataSection.opened}}" visible="false" stepKey="clickOnAddresses1"/> - <selectOption userInput="{{TestSource1.country}}" selector="{{AdminEditSourceAddressDataSection.country}}" stepKey="selectCountry1"/> - <selectOption userInput="{{TestSource1.stateProvince}}" selector="{{AdminEditSourceAddressDataSection.state}}" stepKey="selectState1"/> - <fillField userInput="{{TestSource1.city}}" selector="{{AdminEditSourceAddressDataSection.city}}" stepKey="fillCityField1"/> - <fillField userInput="{{TestSource1.street}}" selector="{{AdminEditSourceAddressDataSection.street}}" stepKey="fillStreetField1"/> - <fillField userInput="{{TestSource1.postcode}}" selector="{{AdminEditSourceAddressDataSection.postcode}}" stepKey="fillPostcodeField1"/> - - <conditionalClick selector="{{AdminEditSourceCarriersSection.closed}}" dependentSelector="{{AdminEditSourceCarriersSection.opened}}" visible="false" stepKey="clickOnCarriers1"/> - <checkOption selector="{{AdminEditSourceCarriersSection.useGlobalShippingConfiguration}}" stepKey="checkUseGlobalShippingConfiguration1"/> - <click selector="{{AdminProductFormActionSection.saveArrow}}" stepKey="clickOnSaveArrow1"/> - <click selector="{{AdminProductFormActionSection.saveAndClose}}" stepKey="clickOnSaveAndClose"/> - - <click selector="{{AdminGridFilterControls.filters}}" stepKey="clickOnFilters1"/> - <fillField userInput="{{TestSource1.source_code}}" selector="{{AdminGridFilterControls.code}}" stepKey="fillCodeField2"/> - <click selector="{{AdminGridFilterControls.applyFilters}}" stepKey="clickOnApplyFilters1"/> - - <see userInput="{{TestSource1.source_code}}" selector="{{AdminGrid.rowOne}}" stepKey="seeCodeInRow1"/> - <see userInput="{{TestSource1.name}}" selector="{{AdminGrid.rowOne}}" stepKey="seeNameInRow1"/> - <see userInput="Enabled" selector="{{AdminGrid.rowOne}}" stepKey="seeIsEnabledInRow1"/> - <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> - <see userInput="0" selector="{{AdminGrid.rowOne}}" stepKey="seePriorityInRow1"/> - </test> -</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceTest.xml deleted file mode 100644 index 745a33b5ef3d3..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminCreateSimpleProductWithDefaultSourceTest.xml +++ /dev/null @@ -1,78 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="AdminCreateSimpleProductWithDefaultSourceTest"> - <annotations> - <features value="Multi-Source Inventory"/> - <stories value="Assign Default Source to New Product"/> - <title value="Simple Product created with Default Source assigned by Admin user"/> - <description value="You should be able to create a New Product, via the Admin, and assign the Default Source to it."/> - <testCaseId value="483"/> - <group value="msi"/> - <group value="bananas"/> - </annotations> - <before> - <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> - - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad"/> - </before> - <after> - <actionGroup ref="logout" stepKey="logoutOfAdmin"/> - <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> - </after> - - <click selector="{{AdminProductGridActionSection.addProductToggle}}" stepKey="clickAddProductDropdown"/> - <click selector="{{AdminProductGridActionSection.addSimpleProduct}}" stepKey="clickAddSimpleProduct"/> - <fillField userInput="{{SimpleMsiProduct.name}}" selector="{{AdminProductFormSection.productName}}" stepKey="fillName"/> - <fillField userInput="{{SimpleMsiProduct.sku}}" selector="{{AdminProductFormSection.productSku}}" stepKey="fillSKU"/> - <fillField userInput="{{SimpleMsiProduct.price}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="fillPrice"/> - <fillField userInput="{{SimpleMsiProduct.weight}}" selector="{{AdminProductFormSection.productWeight}}" stepKey="fillWeight"/> - <searchAndMultiSelectOption selector="{{AdminProductFormSection.categoriesDropdown}}" parameterArray="[$$createPreReqCategory.name$$]" requiredAction="true" stepKey="searchAndSelectCategory"/> - <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSeoSection"/> - <fillField userInput="{{SimpleMsiProduct.urlKey}}" selector="{{AdminProductSEOSection.urlKeyInput}}" stepKey="fillUrlKey"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad1"/> - - <click selector="{{AdminProductSourcesSection.assignSources}}" stepKey="clickOnAssignSource"/> - - <actionGroup ref="AdminClearGridFiltersIfPresent" stepKey="clearGridFiltersIfPresent1"/> - <click selector="{{AdminProductSourcesSidebarSection.defaultSourceCheckbox}}" stepKey="clickOnDefaultSource"/> - <click selector="{{AdminProductSourcesSidebarSection.done}}" stepKey="clickOnDone"/> - - <fillField selector="{{AdminProductSourcesGrid.rowQty}}" userInput="{{SimpleMsiProduct.quantity}}" stepKey="fillQtyField"/> - <fillField selector="{{AdminProductSourcesGrid.rowNotifyQuantity}}" userInput="{{SimpleMsiProduct.notifyQuantity}}" stepKey="fillNotifyQtyField"/> - - <click selector="{{AdminProductFormActionSection.saveArrow}}" stepKey="openSaveDropDown"/> - <click selector="{{AdminProductFormActionSection.saveAndClose}}" stepKey="clickOnSaveAndClose"/> - <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertSaveMessageSuccess"/> - - <see selector="{{AdminProductSourcesGrid.rowId}}" userInput="{{_defaultSource.source_code}}" stepKey="seeDefaultAsId"/> - <see selector="{{AdminProductSourcesGrid.rowName}}" userInput="{{_defaultSource.name}}" stepKey="seeDefaultSourceAsName"/> - <seeOptionIsSelected selector="{{AdminProductSourcesGrid.rowStatus}}" userInput="{{SimpleMsiProduct.stockStatus}}" stepKey="seeInStock"/> - <seeInField selector="{{AdminProductSourcesGrid.rowQty}}" userInput="{{SimpleMsiProduct.quantity}}" stepKey="seeQtyInField"/> - <seeInField selector="{{AdminProductSourcesGrid.rowNotifyQuantity}}" userInput="{{SimpleMsiProduct.notifyQuantity}}" stepKey="seeNotifyQtyInField"/> - - <!-- Go to storefront category page, assert product visibility --> - <amOnPage url="{{StorefrontCategoryPage.url($$createPreReqCategory.name$$)}}" stepKey="navigateToCategoryPage"/> - <waitForPageLoad stepKey="waitForPageLoad3"/> - <see userInput="{{SimpleMsiProduct.name}}" stepKey="assertProductPresent"/> - <see userInput="{{SimpleMsiProduct.price}}" stepKey="assertProductPricePresent"/> - - <!-- Go to storefront product page, assert product visibility --> - <amOnPage url="{{SimpleMsiProduct.urlKey}}.html" stepKey="navigateToProductPage"/> - <waitForPageLoad stepKey="waitForPageLoad4"/> - <seeInTitle userInput="{{SimpleMsiProduct.name}}" stepKey="assertProductNameTitle"/> - <see userInput="{{SimpleMsiProduct.name}}" selector="{{StorefrontProductInfoMainSection.productName}}" stepKey="assertProductName"/> - <see userInput="{{SimpleMsiProduct.price}}" selector="{{StorefrontProductInfoMainSection.productPrice}}" stepKey="assertProductPrice"/> - <see userInput="{{SimpleMsiProduct.sku}}" selector="{{StorefrontProductInfoMainSection.productSku}}" stepKey="assertProductSku"/> - <see userInput="{{SimpleMsiProduct.stockStatus}}" selector="{{StorefrontProductInfoMainSection.productStockStatus}}" stepKey="assertProductStockStatus"/> - </test> -</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminFilterSourcesInGridTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminFilterSourcesInGridTest.xml deleted file mode 100644 index 1d86525a461cd..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminFilterSourcesInGridTest.xml +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="AdminFilterSourcesInGridTest"> - <annotations> - <features value="Multi-Store Inventory"/> - <stories value="Filter Sources in Grid"/> - <title value="Filter Sources on the Manage Sources grid"/> - <description value="You should be able to Filter the Sources from the Manage Sources grid."/> - <testCaseId value="493"/> - <group value="msi"/> - </annotations> - <before> - <createData entity="TestSource1" stepKey="createSource1"/> - <createData entity="TestSource2" stepKey="createSource2"/> - <createData entity="TestSource1" stepKey="createSource3"/> - <createData entity="TestSource2" stepKey="createSource4"/> - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - </before> - <after> - <actionGroup ref="logout" stepKey="logoutOfAdmin"/> - </after> - - <amOnPage url="{{ManageSources.url}}" stepKey="amOnTheSourcesListPage"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> - - <click selector="{{AdminGridFilterControls.filters}}" stepKey="clickOnFilters1"/> - <fillField userInput="$$createSource3.general[source_code]$$" selector="{{AdminGridFilterControls.code}}" stepKey="fillCodeField2"/> - <click selector="{{AdminGridFilterControls.applyFilters}}" stepKey="clickOnApplyFilters1"/> - - <see userInput="$$createSource3.general[source_code]$$" selector="{{AdminGrid.rowOne}}" stepKey="seeCodeInRow1"/> - <see userInput="$$createSource3.general[name]$$" selector="{{AdminGrid.rowOne}}" stepKey="seeNameInRow1"/> - <see userInput="Enabled" selector="{{AdminGrid.rowOne}}" stepKey="seeIsEnabledInRow1"/> - <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> - <see userInput="0" selector="{{AdminGrid.rowOne}}" stepKey="seePriorityInRow1"/> - </test> -</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminUpdateSourceDataTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminUpdateSourceDataTest.xml deleted file mode 100644 index 9b83211c031ed..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MultiSourceInventory/Test/AdminUpdateSourceDataTest.xml +++ /dev/null @@ -1,95 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="AdminUpdateSourceDataTest"> - <annotations> - <features value="Multi-Source Inventory"/> - <stories value="Update existing Source Data"/> - <title value="Source data updated by Admin user"/> - <description value="You should be able to update a Sources data via the Admin."/> - <testCaseId value="492"/> - <group value="msi"/> - </annotations> - - <before> - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - </before> - <after> - <actionGroup ref="logout" stepKey="logoutOfAdmin"/> - </after> - - <amOnPage url="{{ManageSources.url}}" stepKey="amOnTheSourcesListPage1"/> - <click selector="{{AdminManageSourcesGrid.addNewSource}}" stepKey="clickOnAddNewSource1"/> - - <fillField userInput="{{TestSource1.name}}" selector="{{AdminEditSourceGeneralSection.name}}" stepKey="fillNameField1"/> - <fillField userInput="{{TestSource1.source_code}}" selector="{{AdminEditSourceGeneralSection.code}}" stepKey="fillCodeField1"/> - <checkOption selector="{{AdminEditSourceGeneralSection.isEnabled}}" stepKey="checkIsEnabled1"/> - <fillField userInput="{{TestSource1.description}}" selector="{{AdminEditSourceGeneralSection.description}}" stepKey="fillDescriptionField1"/> - - <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> - <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.latitude}}" stepKey="fillLatitudeField1"/> - <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.longitude}}" stepKey="fillLongitudeField1"/> - <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.priority}}" stepKey="fillPriorityField1"/> - - <conditionalClick selector="{{AdminEditSourceContactInfoSection.closed}}" dependentSelector="{{AdminEditSourceContactInfoSection.opened}}" visible="false" stepKey="clickOnContactInfo1"/> - <fillField userInput="{{TestSource1.contact_name}}" selector="{{AdminEditSourceContactInfoSection.contactName}}" stepKey="fillContactNameField1"/> - <fillField userInput="{{TestSource1.email}}" selector="{{AdminEditSourceContactInfoSection.email}}" stepKey="fillEmailField1"/> - <fillField userInput="{{TestSource1.phone}}" selector="{{AdminEditSourceContactInfoSection.phone}}" stepKey="fillPhoneField1"/> - <fillField userInput="{{TestSource1.fax}}" selector="{{AdminEditSourceContactInfoSection.fax}}" stepKey="fillFaxField1"/> - - <conditionalClick selector="{{AdminEditSourceAddressDataSection.closed}}" dependentSelector="{{AdminEditSourceAddressDataSection.opened}}" visible="false" stepKey="clickOnAddresses1"/> - <selectOption userInput="{{TestSource1.country}}" selector="{{AdminEditSourceAddressDataSection.country}}" stepKey="selectCountry1"/> - <selectOption userInput="{{TestSource1.stateProvince}}" selector="{{AdminEditSourceAddressDataSection.state}}" stepKey="selectState1"/> - <fillField userInput="{{TestSource1.city}}" selector="{{AdminEditSourceAddressDataSection.city}}" stepKey="fillCityField1"/> - <fillField userInput="{{TestSource1.street}}" selector="{{AdminEditSourceAddressDataSection.street}}" stepKey="fillStreetField1"/> - <fillField userInput="{{TestSource1.postcode}}" selector="{{AdminEditSourceAddressDataSection.postcode}}" stepKey="fillPostcodeField1"/> - - <conditionalClick selector="{{AdminEditSourceCarriersSection.closed}}" dependentSelector="{{AdminEditSourceCarriersSection.opened}}" visible="false" stepKey="clickOnCarriers1"/> - <checkOption selector="{{AdminEditSourceCarriersSection.useGlobalShippingConfiguration}}" stepKey="checkUseGlobalShippingConfiguration1"/> - - <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickOnSaveContinue1"/> - - <fillField userInput="{{TestSource2.name}}" selector="{{AdminEditSourceGeneralSection.name}}" stepKey="fillNameField2"/> - <fillField userInput="{{TestSource2.source_code}}" selector="{{AdminEditSourceGeneralSection.code}}" stepKey="fillCodeField2"/> - <checkOption selector="{{AdminEditSourceGeneralSection.isEnabled}}" stepKey="checkIsEnabled2"/> - <fillField userInput="{{TestSource2.description}}" selector="{{AdminEditSourceGeneralSection.description}}" stepKey="fillDescriptionField2"/> - - <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> - <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.latitude}}" stepKey="fillLatitudeField2"/> - <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.longitude}}" stepKey="fillLongitudeField2"/> - <fillField userInput="0" selector="{{AdminEditSourceGeneralSection.priority}}" stepKey="fillPriorityField2"/> - - <conditionalClick selector="{{AdminEditSourceContactInfoSection.closed}}" dependentSelector="{{AdminEditSourceContactInfoSection.opened}}" visible="false" stepKey="clickOnContactInfo2"/> - <fillField userInput="{{TestSource2.contact_name}}" selector="{{AdminEditSourceContactInfoSection.contactName}}" stepKey="fillContactNameField2"/> - <fillField userInput="{{TestSource2.email}}" selector="{{AdminEditSourceContactInfoSection.email}}" stepKey="fillEmailField2"/> - <fillField userInput="{{TestSource2.phone}}" selector="{{AdminEditSourceContactInfoSection.phone}}" stepKey="fillPhoneField2"/> - <fillField userInput="{{TestSource2.fax}}" selector="{{AdminEditSourceContactInfoSection.fax}}" stepKey="fillFaxField2"/> - - <conditionalClick selector="{{AdminEditSourceAddressDataSection.closed}}" dependentSelector="{{AdminEditSourceAddressDataSection.opened}}" visible="false" stepKey="clickOnAddresses2"/> - <selectOption userInput="{{TestSource2.country}}" selector="{{AdminEditSourceAddressDataSection.country}}" stepKey="selectCountry2"/> - <selectOption userInput="{{TestSource2.stateProvince}}" selector="{{AdminEditSourceAddressDataSection.state}}" stepKey="selectState2"/> - <fillField userInput="{{TestSource2.city}}" selector="{{AdminEditSourceAddressDataSection.city}}" stepKey="fillCityField2"/> - <fillField userInput="{{TestSource2.street}}" selector="{{AdminEditSourceAddressDataSection.street}}" stepKey="fillStreetField2"/> - <fillField userInput="{{TestSource2.postcode}}" selector="{{AdminEditSourceAddressDataSection.postcode}}" stepKey="fillPostcodeField2"/> - - <click selector="{{AdminProductFormActionSection.saveArrow}}" stepKey="clickOnSaveArrow2"/> - <click selector="{{AdminProductFormActionSection.saveAndClose}}" stepKey="clickOnSaveAndClose2"/> - - <click selector="{{AdminGridFilterControls.filters}}" stepKey="clickOnFilters2"/> - <fillField userInput="{{TestSource2.source_code}}" selector="{{AdminGridFilterControls.code}}" stepKey="fillCodeFieldInGrid2"/> - <click selector="{{AdminGridFilterControls.applyFilters}}" stepKey="clickOnApplyFilters2"/> - - <see userInput="{{TestSource2.source_code}}" selector="{{AdminGrid.rowOne}}" stepKey="seeCodeInRow2"/> - <see userInput="{{TestSource2.name}}" selector="{{AdminGrid.rowOne}}" stepKey="seeNameInRow2"/> - <see userInput="Enabled" selector="{{AdminGrid.rowOne}}" stepKey="seeIsEnabledInRow2"/> - <!--Todo: MQE-677 needs to be merged into Develop before we can use "0" in the Data. Hardcoded "0" for now.--> - <see userInput="0" selector="{{AdminGrid.rowOne}}" stepKey="seePriorityInRow2"/> - </test> -</tests> From 04a91056c8c08973fb2bb98ba93727e58e70c7be Mon Sep 17 00:00:00 2001 From: John Stennett <john00ivy@gmail.com> Date: Thu, 8 Feb 2018 11:25:22 -0600 Subject: [PATCH 023/668] MQE-727: MSI Test Cases - Adding an action group for "AdminGridFilterSearchResultsByInput". - Adding an action group for "AdminGridSearchByKeyword". - Adding an action group for "AdminSaveAndClose". - Adding an action group for "LogoutOfAdmin". --- .../AdminClearGridFiltersActionGroup.xml | 3 ++- ...dminGridFilterSearchResultsActionGroup.xml | 27 +++++++++++++++++++ .../AdminGridSearchByKeywordActionGroup.xml | 25 +++++++++++++++++ .../AdminSaveAndCloseActionGroup.xml | 16 +++++++++++ .../ActionGroup/LogoutOfAdminActionGroup.xml | 14 ++++++++++ 5 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminGridFilterSearchResultsActionGroup.xml create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminGridSearchByKeywordActionGroup.xml create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminSaveAndCloseActionGroup.xml create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/LogoutOfAdminActionGroup.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminClearGridFiltersActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminClearGridFiltersActionGroup.xml index 62c3aec2cafea..6403b7c229f15 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminClearGridFiltersActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminClearGridFiltersActionGroup.xml @@ -10,6 +10,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminClearGridFiltersIfPresent"> <conditionalClick selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .action-remove" dependentSelector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .admin__data-grid-filters-current._show" visible="true" stepKey="clearTheFiltersIfPresent"/> - <waitForPageLoad stepKey="waitForPageLoad"/> + <executeJS function="jQuery('.action-remove').click();" stepKey="clearIfMultipleExist"/> + <waitForPageLoad stepKey="waitForPageLoad" time="5"/> </actionGroup> </actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminGridFilterSearchResultsActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminGridFilterSearchResultsActionGroup.xml new file mode 100644 index 0000000000000..46697dd92629b --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminGridFilterSearchResultsActionGroup.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminGridFilterSearchResultsByInput"> + <arguments> + <argument name="selector"/> + <argument name="value"/> + </arguments> + + <!-- Start of Action Group: AdminClearGridFiltersIfPresent --> + <conditionalClick selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .action-remove" dependentSelector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .admin__data-grid-filters-current._show" visible="true" stepKey="clearTheFiltersIfPresent"/> + <executeJS function="jQuery('.action-remove').click();" stepKey="clearIfMultipleExist"/> + <waitForPageLoad stepKey="waitForPageLoad" time="5"/> + <!-- End of Action Group: AdminClearGridFiltersIfPresent --> + + <click selector="{{AdminGridFilterControls.filters}}" stepKey="clickOnFilters1"/> + <fillField userInput="{{value}}" selector="{{selector}}" stepKey="fillCodeField2"/> + <click selector="{{AdminGridFilterControls.applyFilters}}" stepKey="clickOnApplyFilters1"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminGridSearchByKeywordActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminGridSearchByKeywordActionGroup.xml new file mode 100644 index 0000000000000..32e63279aa72d --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminGridSearchByKeywordActionGroup.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminGridSearchByKeyword"> + <arguments> + <argument name="value"/> + </arguments> + + <!-- Start of Action Group: AdminClearGridFiltersIfPresent --> + <conditionalClick selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .action-remove" dependentSelector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .admin__data-grid-filters-current._show" visible="true" stepKey="clearTheFiltersIfPresent"/> + <executeJS function="jQuery('.action-remove').click();" stepKey="clearIfMultipleExist"/> + <waitForPageLoad stepKey="waitForPageLoad" time="5"/> + <!-- End of Action Group: AdminClearGridFiltersIfPresent --> + + <fillField selector="{{AdminGridSearchBox.searchByKeyword}}" userInput="{{value}}" stepKey="fillSearchByKeyword"/> + <click selector="{{AdminGridSearchBox.search}}" stepKey="clickOnSearch"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminSaveAndCloseActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminSaveAndCloseActionGroup.xml new file mode 100644 index 0000000000000..dc53ed1df9860 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminSaveAndCloseActionGroup.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminSaveAndClose"> + <click selector="{{AdminProductFormActionSection.saveArrow}}" stepKey="openSaveDropDown"/> + <click selector="{{AdminProductFormActionSection.saveAndClose}}" stepKey="clickOnSaveAndClose"/> + <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertSaveMessageSuccess"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/LogoutOfAdminActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/LogoutOfAdminActionGroup.xml new file mode 100644 index 0000000000000..78d6ea42e2d91 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/LogoutOfAdminActionGroup.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="LogoutOfAdmin"> + <amOnPage url="{{_ENV.MAGENTO_BACKEND_NAME}}/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </actionGroup> +</actionGroups> From d2d56d18a67e69f3b6a124bbbcb14424104fdffe Mon Sep 17 00:00:00 2001 From: John Stennett <john00ivy@gmail.com> Date: Wed, 14 Feb 2018 10:53:51 -0600 Subject: [PATCH 024/668] MQE-727: MSI Test Cases - Moving the Admin Grid Action Groups and Sections to the "UI" module. --- .../ActionGroup/AdminClearGridFiltersActionGroup.xml | 0 .../ActionGroup/AdminGridFilterSearchResultsActionGroup.xml | 0 .../ActionGroup/AdminGridSearchByKeywordActionGroup.xml | 0 .../{Backend => Ui}/ActionGroup/AdminSaveAndCloseActionGroup.xml | 0 .../{Backend => Ui}/Section/AdminGridControlsSection.xml | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename dev/tests/acceptance/tests/functional/Magento/FunctionalTest/{Backend => Ui}/ActionGroup/AdminClearGridFiltersActionGroup.xml (100%) rename dev/tests/acceptance/tests/functional/Magento/FunctionalTest/{Backend => Ui}/ActionGroup/AdminGridFilterSearchResultsActionGroup.xml (100%) rename dev/tests/acceptance/tests/functional/Magento/FunctionalTest/{Backend => Ui}/ActionGroup/AdminGridSearchByKeywordActionGroup.xml (100%) rename dev/tests/acceptance/tests/functional/Magento/FunctionalTest/{Backend => Ui}/ActionGroup/AdminSaveAndCloseActionGroup.xml (100%) rename dev/tests/acceptance/tests/functional/Magento/FunctionalTest/{Backend => Ui}/Section/AdminGridControlsSection.xml (100%) diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminClearGridFiltersActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminClearGridFiltersActionGroup.xml similarity index 100% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminClearGridFiltersActionGroup.xml rename to dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminClearGridFiltersActionGroup.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminGridFilterSearchResultsActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminGridFilterSearchResultsActionGroup.xml similarity index 100% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminGridFilterSearchResultsActionGroup.xml rename to dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminGridFilterSearchResultsActionGroup.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminGridSearchByKeywordActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminGridSearchByKeywordActionGroup.xml similarity index 100% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminGridSearchByKeywordActionGroup.xml rename to dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminGridSearchByKeywordActionGroup.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminSaveAndCloseActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminSaveAndCloseActionGroup.xml similarity index 100% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/AdminSaveAndCloseActionGroup.xml rename to dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminSaveAndCloseActionGroup.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridControlsSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/Section/AdminGridControlsSection.xml similarity index 100% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridControlsSection.xml rename to dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/Section/AdminGridControlsSection.xml From 818a84cb7339db3dc1bfca2a2fa5e00cdf4aa38f Mon Sep 17 00:00:00 2001 From: John Stennett <john00ivy@gmail.com> Date: Wed, 14 Feb 2018 16:06:55 -0600 Subject: [PATCH 025/668] MQE-727: MSI Test Cases - Removing the config-metadata, it was pushed to early. --- .../Config/Metadata/config-metadata.xml | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/Metadata/config-metadata.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/Metadata/config-metadata.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/Metadata/config-metadata.xml deleted file mode 100644 index 36eb6a1892e53..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/Metadata/config-metadata.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> - <operation name="UpdateCmsConfiguration" dataType="config_state" type="update" - auth="adminOauth" url="" method=""> - <contentType>application/json</contentType> - <object dataType="config_state" key="config_state"> - <field key="cms_wysiwyg">1</field> - </object> - <object dataType="groups"> - - </object> - </operation> -</operations> From 97c8f819c7c5c256f7be25f325c3437e035a870e Mon Sep 17 00:00:00 2001 From: John Stennett <john00ivy@gmail.com> Date: Fri, 23 Feb 2018 13:14:37 -0600 Subject: [PATCH 026/668] MQE-727: MSI Test Cases - Reverting Robo changes. - Removing the "AdminClearGridFiltersActionGroup". - Replacing AdminClearGridFiltersActionGroup logic with a conditionalClick for the "Clear All" button. - Revised selectors in the Admin Grid section. --- dev/tests/acceptance/RoboFile.php | 2 +- .../AdminClearGridFiltersActionGroup.xml | 16 ---------------- .../AdminGridFilterSearchResultsActionGroup.xml | 5 +---- .../AdminGridSearchByKeywordActionGroup.xml | 5 +---- .../Ui/Section/AdminGridControlsSection.xml | 5 +++-- 5 files changed, 6 insertions(+), 27 deletions(-) delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminClearGridFiltersActionGroup.xml diff --git a/dev/tests/acceptance/RoboFile.php b/dev/tests/acceptance/RoboFile.php index b6e9714bb8f39..51fe3e546a0be 100644 --- a/dev/tests/acceptance/RoboFile.php +++ b/dev/tests/acceptance/RoboFile.php @@ -89,7 +89,7 @@ function functional() */ function group($args = '') { - $this->taskExec('.' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'codecept run functional --debug --skip-group skip --group')->args($args)->run(); + $this->taskExec('.' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'codecept run functional --verbose --steps --skip-group skip --group')->args($args)->run(); } /** diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminClearGridFiltersActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminClearGridFiltersActionGroup.xml deleted file mode 100644 index 6403b7c229f15..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminClearGridFiltersActionGroup.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminClearGridFiltersIfPresent"> - <conditionalClick selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .action-remove" dependentSelector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .admin__data-grid-filters-current._show" visible="true" stepKey="clearTheFiltersIfPresent"/> - <executeJS function="jQuery('.action-remove').click();" stepKey="clearIfMultipleExist"/> - <waitForPageLoad stepKey="waitForPageLoad" time="5"/> - </actionGroup> -</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminGridFilterSearchResultsActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminGridFilterSearchResultsActionGroup.xml index 46697dd92629b..459ad5070da01 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminGridFilterSearchResultsActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminGridFilterSearchResultsActionGroup.xml @@ -14,11 +14,8 @@ <argument name="value"/> </arguments> - <!-- Start of Action Group: AdminClearGridFiltersIfPresent --> - <conditionalClick selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .action-remove" dependentSelector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .admin__data-grid-filters-current._show" visible="true" stepKey="clearTheFiltersIfPresent"/> - <executeJS function="jQuery('.action-remove').click();" stepKey="clearIfMultipleExist"/> + <conditionalClick selector="{{AdminGridFilterControls.clearAll}}" dependentSelector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .admin__data-grid-filters-current._show" visible="true" stepKey="clearTheFiltersIfPresent"/> <waitForPageLoad stepKey="waitForPageLoad" time="5"/> - <!-- End of Action Group: AdminClearGridFiltersIfPresent --> <click selector="{{AdminGridFilterControls.filters}}" stepKey="clickOnFilters1"/> <fillField userInput="{{value}}" selector="{{selector}}" stepKey="fillCodeField2"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminGridSearchByKeywordActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminGridSearchByKeywordActionGroup.xml index 32e63279aa72d..0dfca5eb77fdd 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminGridSearchByKeywordActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminGridSearchByKeywordActionGroup.xml @@ -13,11 +13,8 @@ <argument name="value"/> </arguments> - <!-- Start of Action Group: AdminClearGridFiltersIfPresent --> - <conditionalClick selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .action-remove" dependentSelector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .admin__data-grid-filters-current._show" visible="true" stepKey="clearTheFiltersIfPresent"/> - <executeJS function="jQuery('.action-remove').click();" stepKey="clearIfMultipleExist"/> + <conditionalClick selector="{{AdminGridFilterControls.clearAll}}" dependentSelector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] .admin__data-grid-filters-current._show" visible="true" stepKey="clearTheFiltersIfPresent"/> <waitForPageLoad stepKey="waitForPageLoad" time="5"/> - <!-- End of Action Group: AdminClearGridFiltersIfPresent --> <fillField selector="{{AdminGridSearchBox.searchByKeyword}}" userInput="{{value}}" stepKey="fillSearchByKeyword"/> <click selector="{{AdminGridSearchBox.search}}" stepKey="clickOnSearch"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/Section/AdminGridControlsSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/Section/AdminGridControlsSection.xml index 3421310210490..786b79805d38d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/Section/AdminGridControlsSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/Section/AdminGridControlsSection.xml @@ -30,6 +30,7 @@ <element name="filters" type="button" selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] button[data-action='grid-filter-expand']" timeout="5"/> <element name="applyFilters" type="button" selector="button[data-action='grid-filter-apply']" timeout="30"/> <element name="cancel" type="button" selector="button[data-action='grid-filter-cancel']" timeout="30"/> + <element name="clearAll" type="button" selector=".admin__data-grid-header[data-bind='afterRender: \$data.setToolbarNode'] button[data-action='grid-filter-reset']" timeout="5"/> </section> <!-- TODO: "Default View" drop down menu --> <section name="AdminGridColumnsControls"> @@ -54,9 +55,9 @@ <element name="rowOne" type="text" selector="tr[data-repeat-index='0']"/> <element name="rowByIndex" type="text" selector="tr[data-repeat-index='{{var1}}']" parameterized="true"/> - <element name="editByValue" type="button" selector="//div[@class='data-grid-cell-content'][contains(text(), '{{var1}}')]/parent::*/parent::*/*/a" parameterized="true"/> + <element name="editByValue" type="button" selector="//a[ancestor::tr[contains(., '{{var1}}')]]" parameterized="true"/> - <element name="checkboxByValue" type="checkbox" selector="//div[@class='data-grid-cell-content'][contains(text(), '{{var1}}')]/parent::*/parent::*/*/*/input" parameterized="true"/> + <element name="checkboxByValue" type="checkbox" selector="//input[ancestor::tr[contains(., '{{var1}}')]]" parameterized="true"/> <element name="checkboxByIndex" type="checkbox" selector=".data-row[data-repeat-index='{{var1}}'] .admin__control-checkbox" parameterized="true"/> </section> </sections> From 8f3d47989635a693725025b0859433972bfea786 Mon Sep 17 00:00:00 2001 From: Mohammad HAJ SALEM <haj-salem@e-conomix.at> Date: Mon, 26 Feb 2018 22:21:27 +0100 Subject: [PATCH 027/668] :rocket: update dependancies Update zendframework/zend-mvc 2.6.3 => 2.7.0 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e0db7a4a99a15..adffba24fff02 100644 --- a/composer.json +++ b/composer.json @@ -65,7 +65,7 @@ "zendframework/zend-log": "^2.9.1", "zendframework/zend-mail": "^2.8.0", "zendframework/zend-modulemanager": "^2.7", - "zendframework/zend-mvc": "~2.6.3", + "zendframework/zend-mvc": "~2.7.0", "zendframework/zend-serializer": "^2.7.2", "zendframework/zend-server": "^2.6.1", "zendframework/zend-servicemanager": "^2.7.8", From dcc126aab34ca21d6a4f3f3461140b486917e20c Mon Sep 17 00:00:00 2001 From: Mohammad HAJ SALEM <haj-salem@e-conomix.at> Date: Mon, 26 Feb 2018 22:26:37 +0100 Subject: [PATCH 028/668] :rocket: update dependancies Update zendframework/zend-view 2.9.0 => 2.10.0 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index adffba24fff02..7b62a7aa3e1e0 100644 --- a/composer.json +++ b/composer.json @@ -75,7 +75,7 @@ "zendframework/zend-text": "^2.6.0", "zendframework/zend-uri": "^2.5.1", "zendframework/zend-validator": "^2.6.0", - "zendframework/zend-view": "^2.8.1", + "zendframework/zend-view": "^2.10.0", "webonyx/graphql-php": "^0.11.1" }, "require-dev": { From 76266317b1f20ae15b504979cfdd727c4ba7ec5e Mon Sep 17 00:00:00 2001 From: Mohammad HAJ SALEM <haj-salem@e-conomix.at> Date: Tue, 27 Feb 2018 18:39:18 +0100 Subject: [PATCH 029/668] :rocket: update dependancies Update colinmollenhour/credis 1.6 => 1.9.1 --- composer.json | 2 +- composer.lock | 6336 ------------------------------------------------- 2 files changed, 1 insertion(+), 6337 deletions(-) delete mode 100644 composer.lock diff --git a/composer.json b/composer.json index 7b62a7aa3e1e0..ea0f858f4d05f 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "braintree/braintree_php": "3.22.0", "colinmollenhour/cache-backend-file": "1.4", "colinmollenhour/cache-backend-redis": "1.10.2", - "colinmollenhour/credis": "1.6", + "colinmollenhour/credis": "1.9.1", "colinmollenhour/php-redis-session-abstract": "~1.2.2", "composer/composer": "1.4.1", "magento/composer": "~1.2.0", diff --git a/composer.lock b/composer.lock deleted file mode 100644 index ee6328ed75bb4..0000000000000 --- a/composer.lock +++ /dev/null @@ -1,6336 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "content-hash": "9114dbda66ca0958916c9e26caf374ce", - "packages": [ - { - "name": "braintree/braintree_php", - "version": "3.22.0", - "source": { - "type": "git", - "url": "https://github.com/braintree/braintree_php.git", - "reference": "402617b803779bed5ae899209afa75ef9950becc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/braintree/braintree_php/zipball/402617b803779bed5ae899209afa75ef9950becc", - "reference": "402617b803779bed5ae899209afa75ef9950becc", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-dom": "*", - "ext-hash": "*", - "ext-openssl": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "3.7.*" - }, - "type": "library", - "autoload": { - "psr-0": { - "Braintree": "lib/" - }, - "psr-4": { - "Braintree\\": "lib/Braintree" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Braintree", - "homepage": "http://www.braintreepayments.com" - } - ], - "description": "Braintree PHP Client Library", - "time": "2017-02-16T19:59:04+00:00" - }, - { - "name": "colinmollenhour/cache-backend-file", - "version": "1.4", - "source": { - "type": "git", - "url": "https://github.com/colinmollenhour/Cm_Cache_Backend_File.git", - "reference": "51251b80a817790eb624fbe2afc882c14f3c4fb0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_File/zipball/51251b80a817790eb624fbe2afc882c14f3c4fb0", - "reference": "51251b80a817790eb624fbe2afc882c14f3c4fb0", - "shasum": "" - }, - "require": { - "magento-hackathon/magento-composer-installer": "*" - }, - "type": "magento-module", - "autoload": { - "classmap": [ - "File.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Colin Mollenhour" - } - ], - "description": "The stock Zend_Cache_Backend_File backend has extremely poor performance for cleaning by tags making it become unusable as the number of cached items increases. This backend makes many changes resulting in a huge performance boost, especially for tag cleaning.", - "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_File", - "time": "2016-05-02T16:24:47+00:00" - }, - { - "name": "colinmollenhour/cache-backend-redis", - "version": "1.10.2", - "source": { - "type": "git", - "url": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis.git", - "reference": "18b33e4b69cf15747ab98b4f2c98ab445da05abd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_Redis/zipball/18b33e4b69cf15747ab98b4f2c98ab445da05abd", - "reference": "18b33e4b69cf15747ab98b4f2c98ab445da05abd", - "shasum": "" - }, - "require": { - "magento-hackathon/magento-composer-installer": "*" - }, - "type": "magento-module", - "autoload": { - "classmap": [ - "Cm/Cache/Backend/Redis.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Colin Mollenhour" - } - ], - "description": "Zend_Cache backend using Redis with full support for tags.", - "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis", - "time": "2017-03-25T04:54:24+00:00" - }, - { - "name": "colinmollenhour/credis", - "version": "1.6", - "source": { - "type": "git", - "url": "https://github.com/colinmollenhour/credis.git", - "reference": "409edfd0ea81f5cb74afbdb86df54890c207b5e4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/409edfd0ea81f5cb74afbdb86df54890c207b5e4", - "reference": "409edfd0ea81f5cb74afbdb86df54890c207b5e4", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "Client.php", - "Cluster.php", - "Sentinel.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Colin Mollenhour", - "email": "colin@mollenhour.com" - } - ], - "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", - "homepage": "https://github.com/colinmollenhour/credis", - "time": "2015-11-28T01:20:04+00:00" - }, - { - "name": "colinmollenhour/php-redis-session-abstract", - "version": "v1.2.2", - "source": { - "type": "git", - "url": "https://github.com/colinmollenhour/php-redis-session-abstract.git", - "reference": "46968f06eeed7d16e8476d8a1397e224047ac6ff" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/php-redis-session-abstract/zipball/46968f06eeed7d16e8476d8a1397e224047ac6ff", - "reference": "46968f06eeed7d16e8476d8a1397e224047ac6ff", - "shasum": "" - }, - "require": { - "colinmollenhour/credis": "1.6", - "php": "~5.5.0|~5.6.0|~7.0.0|~7.1.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Cm\\RedisSession\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Colin Mollenhour" - } - ], - "description": "A Redis-based session handler with optimistic locking", - "homepage": "https://github.com/colinmollenhour/php-redis-session-abstract", - "time": "2017-04-19T14:21:43+00:00" - }, - { - "name": "composer/ca-bundle", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/composer/ca-bundle.git", - "reference": "943b2c4fcad1ef178d16a713c2468bf7e579c288" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/943b2c4fcad1ef178d16a713c2468bf7e579c288", - "reference": "943b2c4fcad1ef178d16a713c2468bf7e579c288", - "shasum": "" - }, - "require": { - "ext-openssl": "*", - "ext-pcre": "*", - "php": "^5.3.2 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35", - "psr/log": "^1.0", - "symfony/process": "^2.5 || ^3.0 || ^4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\CaBundle\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", - "keywords": [ - "cabundle", - "cacert", - "certificate", - "ssl", - "tls" - ], - "time": "2017-11-29T09:37:33+00:00" - }, - { - "name": "composer/composer", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/composer/composer.git", - "reference": "7ee2a5e1cf32e9c8439445fe8dce2c046c2abebd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/7ee2a5e1cf32e9c8439445fe8dce2c046c2abebd", - "reference": "7ee2a5e1cf32e9c8439445fe8dce2c046c2abebd", - "shasum": "" - }, - "require": { - "composer/ca-bundle": "^1.0", - "composer/semver": "^1.0", - "composer/spdx-licenses": "^1.0", - "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", - "php": "^5.3.2 || ^7.0", - "psr/log": "^1.0", - "seld/cli-prompt": "^1.0", - "seld/jsonlint": "^1.4", - "seld/phar-utils": "^1.0", - "symfony/console": "^2.7 || ^3.0", - "symfony/filesystem": "^2.7 || ^3.0", - "symfony/finder": "^2.7 || ^3.0", - "symfony/process": "^2.7 || ^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.5 || ^5.0.5", - "phpunit/phpunit-mock-objects": "^2.3 || ^3.0" - }, - "suggest": { - "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", - "ext-zip": "Enabling the zip extension allows you to unzip archives", - "ext-zlib": "Allow gzip compression of HTTP requests" - }, - "bin": [ - "bin/composer" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\": "src/Composer" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", - "homepage": "https://getcomposer.org/", - "keywords": [ - "autoload", - "dependency", - "package" - ], - "time": "2017-03-10T08:29:45+00:00" - }, - { - "name": "composer/semver", - "version": "1.4.2", - "source": { - "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", - "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.5 || ^5.0.5", - "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Semver\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" - } - ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", - "keywords": [ - "semantic", - "semver", - "validation", - "versioning" - ], - "time": "2016-08-30T16:08:34+00:00" - }, - { - "name": "composer/spdx-licenses", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/composer/spdx-licenses.git", - "reference": "7e111c50db92fa2ced140f5ba23b4e261bc77a30" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7e111c50db92fa2ced140f5ba23b4e261bc77a30", - "reference": "7e111c50db92fa2ced140f5ba23b4e261bc77a30", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", - "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Spdx\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" - } - ], - "description": "SPDX licenses list and validation library.", - "keywords": [ - "license", - "spdx", - "validator" - ], - "time": "2018-01-31T13:17:27+00:00" - }, - { - "name": "container-interop/container-interop", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/container-interop/container-interop.git", - "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8", - "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8", - "shasum": "" - }, - "require": { - "psr/container": "^1.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Interop\\Container\\": "src/Interop/Container/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", - "homepage": "https://github.com/container-interop/container-interop", - "time": "2017-02-14T19:40:03+00:00" - }, - { - "name": "justinrainbow/json-schema", - "version": "5.2.6", - "source": { - "type": "git", - "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "d283e11b6e14c6f4664cf080415c4341293e5bbd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/d283e11b6e14c6f4664cf080415c4341293e5bbd", - "reference": "d283e11b6e14c6f4664cf080415c4341293e5bbd", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.1", - "json-schema/json-schema-test-suite": "1.2.0", - "phpunit/phpunit": "^4.8.22" - }, - "bin": [ - "bin/validate-json" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "JsonSchema\\": "src/JsonSchema/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bruno Prieto Reis", - "email": "bruno.p.reis@gmail.com" - }, - { - "name": "Justin Rainbow", - "email": "justin.rainbow@gmail.com" - }, - { - "name": "Igor Wiedler", - "email": "igor@wiedler.ch" - }, - { - "name": "Robert Schönthal", - "email": "seroscho@googlemail.com" - } - ], - "description": "A library to validate a json schema.", - "homepage": "https://github.com/justinrainbow/json-schema", - "keywords": [ - "json", - "schema" - ], - "time": "2017-10-21T13:15:38+00:00" - }, - { - "name": "league/climate", - "version": "2.6.1", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/climate.git", - "reference": "28851c909017424f61cc6a62089316313c645d1c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/climate/zipball/28851c909017424f61cc6a62089316313c645d1c", - "reference": "28851c909017424f61cc6a62089316313c645d1c", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "mockery/mockery": "dev-master", - "phpunit/phpunit": "4.1.*" - }, - "type": "library", - "autoload": { - "psr-4": { - "League\\CLImate\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Joe Tannenbaum", - "email": "hey@joe.codes", - "homepage": "http://joe.codes/", - "role": "Developer" - } - ], - "description": "PHP's best friend for the terminal. CLImate allows you to easily output colored text, special formats, and more.", - "keywords": [ - "cli", - "colors", - "command", - "php", - "terminal" - ], - "time": "2015-01-18T14:31:58+00:00" - }, - { - "name": "magento/composer", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/magento/composer.git", - "reference": "130753af2b755f1967e253deb661225942bb302c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/magento/composer/zipball/130753af2b755f1967e253deb661225942bb302c", - "reference": "130753af2b755f1967e253deb661225942bb302c", - "shasum": "" - }, - "require": { - "composer/composer": "1.4.1", - "php": "~5.5.0|~5.6.0|~7.0.0|~7.1.0", - "symfony/console": "~2.3, !=2.7.0" - }, - "require-dev": { - "phpunit/phpunit": "4.1.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Magento\\Composer\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], - "description": "Magento composer library helps to instantiate Composer application and run composer commands.", - "time": "2017-04-24T09:57:02+00:00" - }, - { - "name": "magento/magento-composer-installer", - "version": "0.1.13", - "source": { - "type": "git", - "url": "https://github.com/magento/magento-composer-installer.git", - "reference": "8b6c32f53b4944a5d6656e86344cd0f9784709a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/magento/magento-composer-installer/zipball/8b6c32f53b4944a5d6656e86344cd0f9784709a1", - "reference": "8b6c32f53b4944a5d6656e86344cd0f9784709a1", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0" - }, - "replace": { - "magento-hackathon/magento-composer-installer": "*" - }, - "require-dev": { - "composer/composer": "*@dev", - "firegento/phpcs": "dev-patch-1", - "mikey179/vfsstream": "*", - "phpunit/phpunit": "*", - "phpunit/phpunit-mock-objects": "dev-master", - "squizlabs/php_codesniffer": "1.4.7", - "symfony/process": "*" - }, - "type": "composer-plugin", - "extra": { - "composer-command-registry": [ - "MagentoHackathon\\Composer\\Magento\\Command\\DeployCommand" - ], - "class": "MagentoHackathon\\Composer\\Magento\\Plugin" - }, - "autoload": { - "psr-0": { - "MagentoHackathon\\Composer\\Magento": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "OSL-3.0" - ], - "authors": [ - { - "name": "Vinai Kopp", - "email": "vinai@netzarbeiter.com" - }, - { - "name": "Daniel Fahlke aka Flyingmana", - "email": "flyingmana@googlemail.com" - }, - { - "name": "Jörg Weller", - "email": "weller@flagbit.de" - }, - { - "name": "Karl Spies", - "email": "karl.spies@gmx.net" - }, - { - "name": "Tobias Vogt", - "email": "tobi@webguys.de" - }, - { - "name": "David Fuhr", - "email": "fuhr@flagbit.de" - } - ], - "description": "Composer installer for Magento modules", - "homepage": "https://github.com/magento/magento-composer-installer", - "keywords": [ - "composer-installer", - "magento" - ], - "time": "2017-12-29T16:45:24+00:00" - }, - { - "name": "magento/zendframework1", - "version": "1.13.1", - "source": { - "type": "git", - "url": "https://github.com/magento/zf1.git", - "reference": "e2693f047bb7ccb8affa8f72ea40269f4c9f4fbf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/magento/zf1/zipball/e2693f047bb7ccb8affa8f72ea40269f4c9f4fbf", - "reference": "e2693f047bb7ccb8affa8f72ea40269f4c9f4fbf", - "shasum": "" - }, - "require": { - "php": ">=5.2.11" - }, - "require-dev": { - "phpunit/dbunit": "1.3.*", - "phpunit/phpunit": "3.7.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.12.x-dev" - } - }, - "autoload": { - "psr-0": { - "Zend_": "library/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "library/" - ], - "license": [ - "BSD-3-Clause" - ], - "description": "Magento Zend Framework 1", - "homepage": "http://framework.zend.com/", - "keywords": [ - "ZF1", - "framework" - ], - "time": "2017-06-21T14:56:23+00:00" - }, - { - "name": "monolog/monolog", - "version": "1.23.0", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4", - "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "psr/log": "~1.0" - }, - "provide": { - "psr/log-implementation": "1.0.0" - }, - "require-dev": { - "aws/aws-sdk-php": "^2.4.9 || ^3.0", - "doctrine/couchdb": "~1.0@dev", - "graylog2/gelf-php": "~1.0", - "jakub-onderka/php-parallel-lint": "0.9", - "php-amqplib/php-amqplib": "~2.4", - "php-console/php-console": "^3.1.3", - "phpunit/phpunit": "~4.5", - "phpunit/phpunit-mock-objects": "2.3.0", - "ruflin/elastica": ">=0.90 <3.0", - "sentry/sentry": "^0.13", - "swiftmailer/swiftmailer": "^5.3|^6.0" - }, - "suggest": { - "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", - "doctrine/couchdb": "Allow sending log messages to a CouchDB server", - "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", - "ext-mongo": "Allow sending log messages to a MongoDB server", - "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", - "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", - "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", - "php-console/php-console": "Allow sending log messages to Google Chrome", - "rollbar/rollbar": "Allow sending log messages to Rollbar", - "ruflin/elastica": "Allow sending log messages to an Elastic Search server", - "sentry/sentry": "Allow sending log messages to a Sentry server" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Monolog\\": "src/Monolog" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "http://github.com/Seldaek/monolog", - "keywords": [ - "log", - "logging", - "psr-3" - ], - "time": "2017-06-19T01:22:40+00:00" - }, - { - "name": "oyejorge/less.php", - "version": "v1.7.0.14", - "source": { - "type": "git", - "url": "https://github.com/oyejorge/less.php.git", - "reference": "42925c5a01a07d67ca7e82dfc8fb31814d557bc9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/oyejorge/less.php/zipball/42925c5a01a07d67ca7e82dfc8fb31814d557bc9", - "reference": "42925c5a01a07d67ca7e82dfc8fb31814d557bc9", - "shasum": "" - }, - "require": { - "php": ">=5.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.8.24" - }, - "bin": [ - "bin/lessc" - ], - "type": "library", - "autoload": { - "psr-0": { - "Less": "lib/" - }, - "classmap": [ - "lessc.inc.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Matt Agar", - "homepage": "https://github.com/agar" - }, - { - "name": "Martin Jantošovič", - "homepage": "https://github.com/Mordred" - }, - { - "name": "Josh Schmidt", - "homepage": "https://github.com/oyejorge" - } - ], - "description": "PHP port of the Javascript version of LESS http://lesscss.org (Originally maintained by Josh Schmidt)", - "homepage": "http://lessphp.gpeasy.com", - "keywords": [ - "css", - "less", - "less.js", - "lesscss", - "php", - "stylesheet" - ], - "time": "2017-03-28T22:19:25+00:00" - }, - { - "name": "paragonie/random_compat", - "version": "v2.0.11", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8", - "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8", - "shasum": "" - }, - "require": { - "php": ">=5.2.0" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "type": "library", - "autoload": { - "files": [ - "lib/random.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "pseudorandom", - "random" - ], - "time": "2017-09-27T21:40:39+00:00" - }, - { - "name": "pelago/emogrifier", - "version": "v2.0.0", - "source": { - "type": "git", - "url": "https://github.com/MyIntervals/emogrifier.git", - "reference": "8babf8ddbf348f26b29674e2f84db66ff7e3d95e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/8babf8ddbf348f26b29674e2f84db66ff7e3d95e", - "reference": "8babf8ddbf348f26b29674e2f84db66ff7e3d95e", - "shasum": "" - }, - "require": { - "php": "^5.5.0 || ~7.0.0 || ~7.1.0 || ~7.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.0", - "squizlabs/php_codesniffer": "^3.1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Pelago\\": "Classes/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "John Reeve", - "email": "jreeve@pelagodesign.com" - }, - { - "name": "Cameron Brooks" - }, - { - "name": "Jaime Prado" - }, - { - "name": "Roman Ožana", - "email": "ozana@omdesign.cz" - }, - { - "name": "Oliver Klee", - "email": "github@oliverklee.de" - }, - { - "name": "Zoli Szabó", - "email": "zoli.szabo+github@gmail.com" - } - ], - "description": "Converts CSS styles into inline style attributes in your HTML code", - "homepage": "https://www.myintervals.com/emogrifier.php", - "keywords": [ - "css", - "email", - "pre-processing" - ], - "time": "2018-01-05T23:30:21+00:00" - }, - { - "name": "phpseclib/phpseclib", - "version": "2.0.9", - "source": { - "type": "git", - "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "c9a3fe35e20eb6eeaca716d6a23cde03f52d1558" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/c9a3fe35e20eb6eeaca716d6a23cde03f52d1558", - "reference": "c9a3fe35e20eb6eeaca716d6a23cde03f52d1558", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phing/phing": "~2.7", - "phpunit/phpunit": "~4.0", - "sami/sami": "~2.0", - "squizlabs/php_codesniffer": "~2.0" - }, - "suggest": { - "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", - "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", - "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", - "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." - }, - "type": "library", - "autoload": { - "files": [ - "phpseclib/bootstrap.php" - ], - "psr-4": { - "phpseclib\\": "phpseclib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" - }, - { - "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" - }, - { - "name": "Andreas Fischer", - "email": "bantu@phpbb.com", - "role": "Developer" - }, - { - "name": "Hans-Jürgen Petrich", - "email": "petrich@tronic-media.com", - "role": "Developer" - }, - { - "name": "Graham Campbell", - "email": "graham@alt-three.com", - "role": "Developer" - } - ], - "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", - "homepage": "http://phpseclib.sourceforge.net", - "keywords": [ - "BigInteger", - "aes", - "asn.1", - "asn1", - "blowfish", - "crypto", - "cryptography", - "encryption", - "rsa", - "security", - "sftp", - "signature", - "signing", - "ssh", - "twofish", - "x.509", - "x509" - ], - "time": "2017-11-29T06:38:08+00:00" - }, - { - "name": "psr/container", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], - "time": "2017-02-14T16:28:37+00:00" - }, - { - "name": "psr/log", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "time": "2016-10-10T12:19:37+00:00" - }, - { - "name": "ramsey/uuid", - "version": "3.6.1", - "source": { - "type": "git", - "url": "https://github.com/ramsey/uuid.git", - "reference": "4ae32dd9ab8860a4bbd750ad269cba7f06f7934e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/4ae32dd9ab8860a4bbd750ad269cba7f06f7934e", - "reference": "4ae32dd9ab8860a4bbd750ad269cba7f06f7934e", - "shasum": "" - }, - "require": { - "paragonie/random_compat": "^1.0|^2.0", - "php": "^5.4 || ^7.0" - }, - "replace": { - "rhumsaa/uuid": "self.version" - }, - "require-dev": { - "apigen/apigen": "^4.1", - "codeception/aspect-mock": "^1.0 | ^2.0", - "doctrine/annotations": "~1.2.0", - "goaop/framework": "1.0.0-alpha.2 | ^1.0 | ^2.1", - "ircmaxell/random-lib": "^1.1", - "jakub-onderka/php-parallel-lint": "^0.9.0", - "mockery/mockery": "^0.9.4", - "moontoast/math": "^1.1", - "php-mock/php-mock-phpunit": "^0.3|^1.1", - "phpunit/phpunit": "^4.7|>=5.0 <5.4", - "satooshi/php-coveralls": "^0.6.1", - "squizlabs/php_codesniffer": "^2.3" - }, - "suggest": { - "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator", - "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator", - "ircmaxell/random-lib": "Provides RandomLib for use with the RandomLibAdapter", - "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).", - "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid", - "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Ramsey\\Uuid\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marijn Huizendveld", - "email": "marijn.huizendveld@gmail.com" - }, - { - "name": "Thibaud Fabre", - "email": "thibaud@aztech.io" - }, - { - "name": "Ben Ramsey", - "email": "ben@benramsey.com", - "homepage": "https://benramsey.com" - } - ], - "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", - "homepage": "https://github.com/ramsey/uuid", - "keywords": [ - "guid", - "identifier", - "uuid" - ], - "time": "2017-03-26T20:37:53+00:00" - }, - { - "name": "seld/cli-prompt", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/cli-prompt.git", - "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/a19a7376a4689d4d94cab66ab4f3c816019ba8dd", - "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd", - "shasum": "" - }, - "require": { - "php": ">=5.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Seld\\CliPrompt\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "Allows you to prompt for user input on the command line, and optionally hide the characters they type", - "keywords": [ - "cli", - "console", - "hidden", - "input", - "prompt" - ], - "time": "2017-03-18T11:32:45+00:00" - }, - { - "name": "seld/jsonlint", - "version": "1.7.1", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "d15f59a67ff805a44c50ea0516d2341740f81a38" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/d15f59a67ff805a44c50ea0516d2341740f81a38", - "reference": "d15f59a67ff805a44c50ea0516d2341740f81a38", - "shasum": "" - }, - "require": { - "php": "^5.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "bin": [ - "bin/jsonlint" - ], - "type": "library", - "autoload": { - "psr-4": { - "Seld\\JsonLint\\": "src/Seld/JsonLint/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "JSON Linter", - "keywords": [ - "json", - "linter", - "parser", - "validator" - ], - "time": "2018-01-24T12:46:19+00:00" - }, - { - "name": "seld/phar-utils", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/phar-utils.git", - "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/7009b5139491975ef6486545a39f3e6dad5ac30a", - "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a", - "shasum": "" - }, - "require": { - "php": ">=5.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Seld\\PharUtils\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "PHAR file format utilities, for when PHP phars you up", - "keywords": [ - "phra" - ], - "time": "2015-10-13T18:44:15+00:00" - }, - { - "name": "sjparkinson/static-review", - "version": "4.1.1", - "source": { - "type": "git", - "url": "https://github.com/sjparkinson/static-review.git", - "reference": "493c3410cf146a12fca84209bad126c494e125f0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sjparkinson/static-review/zipball/493c3410cf146a12fca84209bad126c494e125f0", - "reference": "493c3410cf146a12fca84209bad126c494e125f0", - "shasum": "" - }, - "require": { - "league/climate": "~2.0", - "php": ">=5.4.0", - "symfony/console": "~2.0", - "symfony/process": "~2.0" - }, - "require-dev": { - "mockery/mockery": "~0.9", - "phpunit/phpunit": "~4.0", - "sensiolabs/security-checker": "~2.0", - "squizlabs/php_codesniffer": "~1.0" - }, - "suggest": { - "sensiolabs/security-checker": "Required for ComposerSecurityReview.", - "squizlabs/php_codesniffer": "Required for PhpCodeSnifferReview." - }, - "bin": [ - "bin/static-review.php" - ], - "type": "library", - "autoload": { - "psr-4": { - "StaticReview\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Samuel Parkinson", - "email": "sam.james.parkinson@gmail.com", - "homepage": "http://samp.im" - } - ], - "description": "An extendable framework for version control hooks.", - "abandoned": "phpro/grumphp", - "time": "2014-09-22T08:40:36+00:00" - }, - { - "name": "symfony/console", - "version": "v2.8.34", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "162ca7d0ea597599967aa63b23418e747da0896b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/162ca7d0ea597599967aa63b23418e747da0896b", - "reference": "162ca7d0ea597599967aa63b23418e747da0896b", - "shasum": "" - }, - "require": { - "php": ">=5.3.9", - "symfony/debug": "^2.7.2|~3.0.0", - "symfony/polyfill-mbstring": "~1.0" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1|~3.0.0", - "symfony/process": "~2.1|~3.0.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/process": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Console Component", - "homepage": "https://symfony.com", - "time": "2018-01-29T08:54:45+00:00" - }, - { - "name": "symfony/debug", - "version": "v3.0.9", - "source": { - "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/697c527acd9ea1b2d3efac34d9806bf255278b0a", - "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "psr/log": "~1.0" - }, - "conflict": { - "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" - }, - "require-dev": { - "symfony/class-loader": "~2.8|~3.0", - "symfony/http-kernel": "~2.8|~3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Debug\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Debug Component", - "homepage": "https://symfony.com", - "time": "2016-07-30T07:22:48+00:00" - }, - { - "name": "symfony/event-dispatcher", - "version": "v2.8.34", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "d64be24fc1eba62f9daace8a8918f797fc8e87cc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d64be24fc1eba62f9daace8a8918f797fc8e87cc", - "reference": "d64be24fc1eba62f9daace8a8918f797fc8e87cc", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.6|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony EventDispatcher Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:36:31+00:00" - }, - { - "name": "symfony/filesystem", - "version": "v3.4.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "e078773ad6354af38169faf31c21df0f18ace03d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/e078773ad6354af38169faf31c21df0f18ace03d", - "reference": "e078773ad6354af38169faf31c21df0f18ace03d", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Filesystem Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "symfony/finder", - "version": "v3.4.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/613e26310776f49a1773b6737c6bd554b8bc8c6f", - "reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Finder Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b", - "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-30T19:27:44+00:00" - }, - { - "name": "symfony/process", - "version": "v2.8.34", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "905efe90024caa75a2fc93f54e14b26f2a099d96" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/905efe90024caa75a2fc93f54e14b26f2a099d96", - "reference": "905efe90024caa75a2fc93f54e14b26f2a099d96", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Process Component", - "homepage": "https://symfony.com", - "time": "2018-01-29T08:54:45+00:00" - }, - { - "name": "tedivm/jshrink", - "version": "v1.1.0", - "source": { - "type": "git", - "url": "https://github.com/tedious/JShrink.git", - "reference": "688527a2e854d7935f24f24c7d5eb1b604742bf9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tedious/JShrink/zipball/688527a2e854d7935f24f24c7d5eb1b604742bf9", - "reference": "688527a2e854d7935f24f24c7d5eb1b604742bf9", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "fabpot/php-cs-fixer": "0.4.0", - "phpunit/phpunit": "4.0.*", - "satooshi/php-coveralls": "dev-master" - }, - "type": "library", - "autoload": { - "psr-0": { - "JShrink": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Robert Hafner", - "email": "tedivm@tedivm.com" - } - ], - "description": "Javascript Minifier built in PHP", - "homepage": "http://github.com/tedious/JShrink", - "keywords": [ - "javascript", - "minifier" - ], - "time": "2015-07-04T07:35:09+00:00" - }, - { - "name": "tubalmartin/cssmin", - "version": "v4.1.0", - "source": { - "type": "git", - "url": "https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port.git", - "reference": "1c7ae93cf6b392d4dae5c4ae18979918413af16e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tubalmartin/YUI-CSS-compressor-PHP-port/zipball/1c7ae93cf6b392d4dae5c4ae18979918413af16e", - "reference": "1c7ae93cf6b392d4dae5c4ae18979918413af16e", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "php": ">=5.3.2" - }, - "require-dev": { - "cogpowered/finediff": "0.3.*", - "phpunit/phpunit": "4.8.*" - }, - "bin": [ - "cssmin" - ], - "type": "library", - "autoload": { - "psr-4": { - "tubalmartin\\CssMin\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Túbal Martín", - "homepage": "http://tubalmartin.me/" - } - ], - "description": "A PHP port of the YUI CSS compressor", - "homepage": "https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port", - "keywords": [ - "compress", - "compressor", - "css", - "cssmin", - "minify", - "yui" - ], - "time": "2017-05-16T13:45:26+00:00" - }, - { - "name": "webonyx/graphql-php", - "version": "v0.11.5", - "source": { - "type": "git", - "url": "https://github.com/webonyx/graphql-php.git", - "reference": "b97cad0f4a50131c85d9224e8e36ebbcf1c6b425" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webonyx/graphql-php/zipball/b97cad0f4a50131c85d9224e8e36ebbcf1c6b425", - "reference": "b97cad0f4a50131c85d9224e8e36ebbcf1c6b425", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=5.5,<8.0-DEV" - }, - "require-dev": { - "phpunit/phpunit": "^4.8", - "psr/http-message": "^1.0" - }, - "suggest": { - "psr/http-message": "To use standard GraphQL server", - "react/promise": "To leverage async resolving on React PHP platform" - }, - "type": "library", - "autoload": { - "files": [ - "src/deprecated.php" - ], - "psr-4": { - "GraphQL\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD" - ], - "description": "A PHP port of GraphQL reference implementation", - "homepage": "https://github.com/webonyx/graphql-php", - "keywords": [ - "api", - "graphql" - ], - "time": "2017-12-12T09:03:21+00:00" - }, - { - "name": "zendframework/zend-captcha", - "version": "2.7.1", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-captcha.git", - "reference": "2d56293a5ae3e45e7c8ee7030aa8b305768d8014" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-captcha/zipball/2d56293a5ae3e45e7c8ee7030aa8b305768d8014", - "reference": "2d56293a5ae3e45e7c8ee7030aa8b305768d8014", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0", - "zendframework/zend-math": "^2.6 || ^3.0", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-session": "^2.6", - "zendframework/zend-text": "^2.6", - "zendframework/zend-validator": "^2.6", - "zendframework/zendservice-recaptcha": "^3.0" - }, - "suggest": { - "zendframework/zend-i18n-resources": "Translations of captcha messages", - "zendframework/zend-session": "Zend\\Session component", - "zendframework/zend-text": "Zend\\Text component", - "zendframework/zend-validator": "Zend\\Validator component", - "zendframework/zendservice-recaptcha": "ZendService\\ReCaptcha component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Captcha\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-captcha", - "keywords": [ - "captcha", - "zf2" - ], - "time": "2017-02-23T08:09:44+00:00" - }, - { - "name": "zendframework/zend-code", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-code.git", - "reference": "2899c17f83a7207f2d7f53ec2f421204d3beea27" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-code/zipball/2899c17f83a7207f2d7f53ec2f421204d3beea27", - "reference": "2899c17f83a7207f2d7f53ec2f421204d3beea27", - "shasum": "" - }, - "require": { - "php": "^5.6 || 7.0.0 - 7.0.4 || ^7.0.6", - "zendframework/zend-eventmanager": "^2.6 || ^3.0" - }, - "require-dev": { - "doctrine/annotations": "~1.0", - "ext-phar": "*", - "phpunit/phpunit": "^4.8.21", - "squizlabs/php_codesniffer": "^2.5", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "suggest": { - "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", - "zendframework/zend-stdlib": "Zend\\Stdlib component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev", - "dev-develop": "3.2-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Code\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides facilities to generate arbitrary code using an object oriented interface", - "homepage": "https://github.com/zendframework/zend-code", - "keywords": [ - "code", - "zf2" - ], - "time": "2016-10-24T13:23:32+00:00" - }, - { - "name": "zendframework/zend-config", - "version": "2.6.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-config.git", - "reference": "2920e877a9f6dca9fa8f6bd3b1ffc2e19bb1e30d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-config/zipball/2920e877a9f6dca9fa8f6bd3b1ffc2e19bb1e30d", - "reference": "2920e877a9f6dca9fa8f6bd3b1ffc2e19bb1e30d", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0", - "zendframework/zend-filter": "^2.6", - "zendframework/zend-i18n": "^2.5", - "zendframework/zend-json": "^2.6.1", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3" - }, - "suggest": { - "zendframework/zend-filter": "Zend\\Filter component", - "zendframework/zend-i18n": "Zend\\I18n component", - "zendframework/zend-json": "Zend\\Json to use the Json reader or writer classes", - "zendframework/zend-servicemanager": "Zend\\ServiceManager for use with the Config Factory to retrieve reader and writer instances" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev", - "dev-develop": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Config\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides a nested object property based user interface for accessing this configuration data within application code", - "homepage": "https://github.com/zendframework/zend-config", - "keywords": [ - "config", - "zf2" - ], - "time": "2016-02-04T23:01:10+00:00" - }, - { - "name": "zendframework/zend-console", - "version": "2.7.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-console.git", - "reference": "e8aa08da83de3d265256c40ba45cd649115f0e18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-console/zipball/e8aa08da83de3d265256c40ba45cd649115f0e18", - "reference": "e8aa08da83de3d265256c40ba45cd649115f0e18", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0", - "zendframework/zend-stdlib": "^2.7.7 || ^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^5.7.23 || ^6.4.3", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-filter": "^2.7.2", - "zendframework/zend-json": "^2.6 || ^3.0", - "zendframework/zend-validator": "^2.10.1" - }, - "suggest": { - "zendframework/zend-filter": "To support DefaultRouteMatcher usage", - "zendframework/zend-validator": "To support DefaultRouteMatcher usage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7.x-dev", - "dev-develop": "2.8.x-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Console\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Build console applications using getopt syntax or routing, complete with prompts", - "keywords": [ - "ZendFramework", - "console", - "zf" - ], - "time": "2018-01-25T19:08:04+00:00" - }, - { - "name": "zendframework/zend-crypt", - "version": "2.6.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-crypt.git", - "reference": "1b2f5600bf6262904167116fa67b58ab1457036d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-crypt/zipball/1b2f5600bf6262904167116fa67b58ab1457036d", - "reference": "1b2f5600bf6262904167116fa67b58ab1457036d", - "shasum": "" - }, - "require": { - "container-interop/container-interop": "~1.0", - "php": "^5.5 || ^7.0", - "zendframework/zend-math": "^2.6", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "ext-mcrypt": "Required for most features of Zend\\Crypt" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev", - "dev-develop": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Crypt\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-crypt", - "keywords": [ - "crypt", - "zf2" - ], - "time": "2016-02-03T23:46:30+00:00" - }, - { - "name": "zendframework/zend-db", - "version": "2.9.2", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-db.git", - "reference": "1651abb1b33fc8fbd2d78ff9e2abb526cc2cf666" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-db/zipball/1651abb1b33fc8fbd2d78ff9e2abb526cc2cf666", - "reference": "1651abb1b33fc8fbd2d78ff9e2abb526cc2cf666", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7.25 || ^6.4.4", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", - "zendframework/zend-hydrator": "^1.1 || ^2.1", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3" - }, - "suggest": { - "zendframework/zend-eventmanager": "Zend\\EventManager component", - "zendframework/zend-hydrator": "Zend\\Hydrator component for using HydratingResultSets", - "zendframework/zend-servicemanager": "Zend\\ServiceManager component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.9-dev", - "dev-develop": "2.10-dev" - }, - "zf": { - "component": "Zend\\Db", - "config-provider": "Zend\\Db\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Zend\\Db\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Database abstraction layer, SQL abstraction, result set abstraction, and RowDataGateway and TableDataGateway implementations", - "keywords": [ - "ZendFramework", - "db", - "zf" - ], - "time": "2017-12-11T14:57:52+00:00" - }, - { - "name": "zendframework/zend-di", - "version": "2.6.1", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-di.git", - "reference": "1fd1ba85660b5a2718741b38639dc7c4c3194b37" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-di/zipball/1fd1ba85660b5a2718741b38639dc7c4c3194b37", - "reference": "1fd1ba85660b5a2718741b38639dc7c4c3194b37", - "shasum": "" - }, - "require": { - "container-interop/container-interop": "^1.1", - "php": "^5.5 || ^7.0", - "zendframework/zend-code": "^2.6 || ^3.0", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev", - "dev-develop": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Di\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-di", - "keywords": [ - "di", - "zf2" - ], - "time": "2016-04-25T20:58:11+00:00" - }, - { - "name": "zendframework/zend-escaper", - "version": "2.5.2", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-escaper.git", - "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/2dcd14b61a72d8b8e27d579c6344e12c26141d4e", - "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Escaper\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-escaper", - "keywords": [ - "escaper", - "zf2" - ], - "time": "2016-06-30T19:48:38+00:00" - }, - { - "name": "zendframework/zend-eventmanager", - "version": "2.6.4", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-eventmanager.git", - "reference": "d238c443220dce4b6396579c8ab2200ec25f9108" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/d238c443220dce4b6396579c8ab2200ec25f9108", - "reference": "d238c443220dce4b6396579c8ab2200ec25f9108", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "zendframework/zend-stdlib": "^2.7" - }, - "require-dev": { - "athletic/athletic": "dev-master", - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-release-2.6": "2.6-dev", - "dev-master": "3.0-dev", - "dev-develop": "3.1-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\EventManager\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-eventmanager", - "keywords": [ - "eventmanager", - "zf2" - ], - "time": "2017-12-12T17:48:56+00:00" - }, - { - "name": "zendframework/zend-filter", - "version": "2.7.2", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-filter.git", - "reference": "b8d0ff872f126631bf63a932e33aa2d22d467175" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-filter/zipball/b8d0ff872f126631bf63a932e33aa2d22d467175", - "reference": "b8d0ff872f126631bf63a932e33aa2d22d467175", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "require-dev": { - "pear/archive_tar": "^1.4", - "phpunit/phpunit": "^6.0.10 || ^5.7.17", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-crypt": "^2.6 || ^3.0", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", - "zendframework/zend-uri": "^2.5" - }, - "suggest": { - "zendframework/zend-crypt": "Zend\\Crypt component, for encryption filters", - "zendframework/zend-i18n": "Zend\\I18n component for filters depending on i18n functionality", - "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for using the filter chain functionality", - "zendframework/zend-uri": "Zend\\Uri component, for the UriNormalize filter" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" - }, - "zf": { - "component": "Zend\\Filter", - "config-provider": "Zend\\Filter\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Zend\\Filter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides a set of commonly needed data filters", - "homepage": "https://github.com/zendframework/zend-filter", - "keywords": [ - "filter", - "zf2" - ], - "time": "2017-05-17T20:56:17+00:00" - }, - { - "name": "zendframework/zend-form", - "version": "2.11.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-form.git", - "reference": "b68a9f07d93381613b68817091d0505ca94d3363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-form/zipball/b68a9f07d93381613b68817091d0505ca94d3363", - "reference": "b68a9f07d93381613b68817091d0505ca94d3363", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0", - "zendframework/zend-hydrator": "^1.1 || ^2.1", - "zendframework/zend-inputfilter": "^2.8", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "require-dev": { - "doctrine/annotations": "~1.0", - "phpunit/phpunit": "^5.7.23 || ^6.5.3", - "zendframework/zend-cache": "^2.6.1", - "zendframework/zend-captcha": "^2.7.1", - "zendframework/zend-code": "^2.6 || ^3.0", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-escaper": "^2.5", - "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", - "zendframework/zend-filter": "^2.6", - "zendframework/zend-i18n": "^2.6", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", - "zendframework/zend-session": "^2.8.1", - "zendframework/zend-text": "^2.6", - "zendframework/zend-validator": "^2.6", - "zendframework/zend-view": "^2.6.2", - "zendframework/zendservice-recaptcha": "^3.0.0" - }, - "suggest": { - "zendframework/zend-captcha": "^2.7.1, required for using CAPTCHA form elements", - "zendframework/zend-code": "^2.6 || ^3.0, required to use zend-form annotations support", - "zendframework/zend-eventmanager": "^2.6.2 || ^3.0, reuired for zend-form annotations support", - "zendframework/zend-i18n": "^2.6, required when using zend-form view helpers", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3, required to use the form factories or provide services", - "zendframework/zend-view": "^2.6.2, required for using the zend-form view helpers", - "zendframework/zendservice-recaptcha": "in order to use the ReCaptcha form element" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.11.x-dev", - "dev-develop": "2.12.x-dev" - }, - "zf": { - "component": "Zend\\Form", - "config-provider": "Zend\\Form\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Zend\\Form\\": "src/" - }, - "files": [ - "autoload/formElementManagerPolyfill.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Validate and display simple and complex forms, casting forms to business objects and vice versa", - "keywords": [ - "ZendFramework", - "form", - "zf" - ], - "time": "2017-12-06T21:09:08+00:00" - }, - { - "name": "zendframework/zend-http", - "version": "2.7.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-http.git", - "reference": "78aa510c0ea64bfb2aa234f50c4f232c9531acfa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-http/zipball/78aa510c0ea64bfb2aa234f50c4f232c9531acfa", - "reference": "78aa510c0ea64bfb2aa234f50c4f232c9531acfa", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0", - "zendframework/zend-loader": "^2.5.1", - "zendframework/zend-stdlib": "^3.1 || ^2.7.7", - "zendframework/zend-uri": "^2.5.2", - "zendframework/zend-validator": "^2.10.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.4.1 || ^5.7.15", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-config": "^3.1 || ^2.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Http\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides an easy interface for performing Hyper-Text Transfer Protocol (HTTP) requests", - "homepage": "https://github.com/zendframework/zend-http", - "keywords": [ - "ZendFramework", - "http", - "http client", - "zend", - "zf" - ], - "time": "2017-10-13T12:06:24+00:00" - }, - { - "name": "zendframework/zend-hydrator", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-hydrator.git", - "reference": "22652e1661a5a10b3f564cf7824a2206cf5a4a65" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-hydrator/zipball/22652e1661a5a10b3f564cf7824a2206cf5a4a65", - "reference": "22652e1661a5a10b3f564cf7824a2206cf5a4a65", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "^2.0@dev", - "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", - "zendframework/zend-filter": "^2.6", - "zendframework/zend-inputfilter": "^2.6", - "zendframework/zend-serializer": "^2.6.1", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3" - }, - "suggest": { - "zendframework/zend-eventmanager": "^2.6.2 || ^3.0, to support aggregate hydrator usage", - "zendframework/zend-filter": "^2.6, to support naming strategy hydrator usage", - "zendframework/zend-serializer": "^2.6.1, to use the SerializableStrategy", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3, to support hydrator plugin manager usage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-release-1.0": "1.0-dev", - "dev-release-1.1": "1.1-dev", - "dev-master": "2.0-dev", - "dev-develop": "2.1-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Hydrator\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-hydrator", - "keywords": [ - "hydrator", - "zf2" - ], - "time": "2016-02-18T22:38:26+00:00" - }, - { - "name": "zendframework/zend-i18n", - "version": "2.7.4", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-i18n.git", - "reference": "d3431e29cc00c2a1c6704e601d4371dbf24f6a31" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-i18n/zipball/d3431e29cc00c2a1c6704e601d4371dbf24f6a31", - "reference": "d3431e29cc00c2a1c6704e601d4371dbf24f6a31", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^5.6", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0.8 || ^5.7.15", - "zendframework/zend-cache": "^2.6.1", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-config": "^2.6", - "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", - "zendframework/zend-filter": "^2.6.1", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", - "zendframework/zend-validator": "^2.6", - "zendframework/zend-view": "^2.6.3" - }, - "suggest": { - "ext-intl": "Required for most features of Zend\\I18n; included in default builds of PHP", - "zendframework/zend-cache": "Zend\\Cache component", - "zendframework/zend-config": "Zend\\Config component", - "zendframework/zend-eventmanager": "You should install this package to use the events in the translator", - "zendframework/zend-filter": "You should install this package to use the provided filters", - "zendframework/zend-i18n-resources": "Translation resources", - "zendframework/zend-servicemanager": "Zend\\ServiceManager component", - "zendframework/zend-validator": "You should install this package to use the provided validators", - "zendframework/zend-view": "You should install this package to use the provided view helpers" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" - }, - "zf": { - "component": "Zend\\I18n", - "config-provider": "Zend\\I18n\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Zend\\I18n\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-i18n", - "keywords": [ - "i18n", - "zf2" - ], - "time": "2017-05-17T17:00:12+00:00" - }, - { - "name": "zendframework/zend-inputfilter", - "version": "2.8.1", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-inputfilter.git", - "reference": "55d1430db559e9781b147e73c2c0ce6635d8efe2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-inputfilter/zipball/55d1430db559e9781b147e73c2c0ce6635d8efe2", - "reference": "55d1430db559e9781b147e73c2c0ce6635d8efe2", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0", - "zendframework/zend-filter": "^2.6", - "zendframework/zend-servicemanager": "^2.7.10 || ^3.3.1", - "zendframework/zend-stdlib": "^2.7 || ^3.0", - "zendframework/zend-validator": "^2.10.1" - }, - "require-dev": { - "phpunit/phpunit": "^5.7.23 || ^6.4.3", - "zendframework/zend-coding-standard": "~1.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8.x-dev", - "dev-develop": "2.9.x-dev" - }, - "zf": { - "component": "Zend\\InputFilter", - "config-provider": "Zend\\InputFilter\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Zend\\InputFilter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Normalize and validate input sets from the web, APIs, the CLI, and more, including files", - "keywords": [ - "ZendFramework", - "inputfilter", - "zf" - ], - "time": "2018-01-22T19:41:18+00:00" - }, - { - "name": "zendframework/zend-json", - "version": "2.6.1", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-json.git", - "reference": "4c8705dbe4ad7d7e51b2876c5b9eea0ef916ba28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-json/zipball/4c8705dbe4ad7d7e51b2876c5b9eea0ef916ba28", - "reference": "4c8705dbe4ad7d7e51b2876c5b9eea0ef916ba28", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0" - }, - "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0", - "zendframework/zend-http": "^2.5.4", - "zendframework/zend-server": "^2.6.1", - "zendframework/zend-stdlib": "^2.5 || ^3.0", - "zendframework/zendxml": "^1.0.2" - }, - "suggest": { - "zendframework/zend-http": "Zend\\Http component, required to use Zend\\Json\\Server", - "zendframework/zend-server": "Zend\\Server component, required to use Zend\\Json\\Server", - "zendframework/zend-stdlib": "Zend\\Stdlib component, for use with caching Zend\\Json\\Server responses", - "zendframework/zendxml": "To support Zend\\Json\\Json::fromXml() usage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev", - "dev-develop": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Json\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides convenience methods for serializing native PHP to JSON and decoding JSON to native PHP", - "homepage": "https://github.com/zendframework/zend-json", - "keywords": [ - "json", - "zf2" - ], - "time": "2016-02-04T21:20:26+00:00" - }, - { - "name": "zendframework/zend-loader", - "version": "2.5.1", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-loader.git", - "reference": "c5fd2f071bde071f4363def7dea8dec7393e135c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/c5fd2f071bde071f4363def7dea8dec7393e135c", - "reference": "c5fd2f071bde071f4363def7dea8dec7393e135c", - "shasum": "" - }, - "require": { - "php": ">=5.3.23" - }, - "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Loader\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-loader", - "keywords": [ - "loader", - "zf2" - ], - "time": "2015-06-03T14:05:47+00:00" - }, - { - "name": "zendframework/zend-log", - "version": "2.9.2", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-log.git", - "reference": "bf7489578d092d6ff7508117d1d920a4764fbd6a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-log/zipball/bf7489578d092d6ff7508117d1d920a4764fbd6a", - "reference": "bf7489578d092d6ff7508117d1d920a4764fbd6a", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0", - "psr/log": "^1.0", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "provide": { - "psr/log-implementation": "1.0.0" - }, - "require-dev": { - "mikey179/vfsstream": "^1.6", - "phpunit/phpunit": "^5.7.15 || ^6.0.8", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-db": "^2.6", - "zendframework/zend-escaper": "^2.5", - "zendframework/zend-filter": "^2.5", - "zendframework/zend-mail": "^2.6.1", - "zendframework/zend-validator": "^2.6" - }, - "suggest": { - "ext-mongo": "mongo extension to use Mongo writer", - "ext-mongodb": "mongodb extension to use MongoDB writer", - "zendframework/zend-console": "Zend\\Console component to use the RequestID log processor", - "zendframework/zend-db": "Zend\\Db component to use the database log writer", - "zendframework/zend-escaper": "Zend\\Escaper component, for use in the XML log formatter", - "zendframework/zend-mail": "Zend\\Mail component to use the email log writer", - "zendframework/zend-validator": "Zend\\Validator component to block invalid log messages" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.9-dev", - "dev-develop": "2.10-dev" - }, - "zf": { - "component": "Zend\\Log", - "config-provider": "Zend\\Log\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Zend\\Log\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "component for general purpose logging", - "homepage": "https://github.com/zendframework/zend-log", - "keywords": [ - "log", - "logging", - "zf2" - ], - "time": "2017-05-17T16:03:26+00:00" - }, - { - "name": "zendframework/zend-mail", - "version": "2.8.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-mail.git", - "reference": "248230940ab1453b2a532a8fde76c5a6470d7aad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-mail/zipball/248230940ab1453b2a532a8fde76c5a6470d7aad", - "reference": "248230940ab1453b2a532a8fde76c5a6470d7aad", - "shasum": "" - }, - "require": { - "ext-iconv": "*", - "php": "^7.0 || ^5.6", - "zendframework/zend-loader": "^2.5", - "zendframework/zend-mime": "^2.5", - "zendframework/zend-stdlib": "^2.7 || ^3.0", - "zendframework/zend-validator": "^2.6" - }, - "require-dev": { - "phpunit/phpunit": "^6.0.8 || ^5.7.15", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-config": "^2.6", - "zendframework/zend-crypt": "^2.6", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3" - }, - "suggest": { - "ext-intl": "Handle IDN in AddressList hostnames", - "zendframework/zend-crypt": "Crammd5 support in SMTP Auth", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3 when using SMTP to deliver messages" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev", - "dev-develop": "2.9-dev" - }, - "zf": { - "component": "Zend\\Mail", - "config-provider": "Zend\\Mail\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Zend\\Mail\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides generalized functionality to compose and send both text and MIME-compliant multipart e-mail messages", - "homepage": "https://github.com/zendframework/zend-mail", - "keywords": [ - "mail", - "zf2" - ], - "time": "2017-06-08T20:03:58+00:00" - }, - { - "name": "zendframework/zend-math", - "version": "2.7.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-math.git", - "reference": "f4358090d5d23973121f1ed0b376184b66d9edec" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-math/zipball/f4358090d5d23973121f1ed0b376184b66d9edec", - "reference": "f4358090d5d23973121f1ed0b376184b66d9edec", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0" - }, - "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "ircmaxell/random-lib": "~1.1", - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "ext-bcmath": "If using the bcmath functionality", - "ext-gmp": "If using the gmp functionality", - "ircmaxell/random-lib": "Fallback random byte generator for Zend\\Math\\Rand if Mcrypt extensions is unavailable" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Math\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-math", - "keywords": [ - "math", - "zf2" - ], - "time": "2016-04-07T16:29:53+00:00" - }, - { - "name": "zendframework/zend-mime", - "version": "2.7.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-mime.git", - "reference": "5db38e92f8a6c7c5e25c8afce6e2d0bd49340c5f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-mime/zipball/5db38e92f8a6c7c5e25c8afce6e2d0bd49340c5f", - "reference": "5db38e92f8a6c7c5e25c8afce6e2d0bd49340c5f", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7.21 || ^6.3", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-mail": "^2.6" - }, - "suggest": { - "zendframework/zend-mail": "Zend\\Mail component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Mime\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Create and parse MIME messages and parts", - "homepage": "https://github.com/zendframework/zend-mime", - "keywords": [ - "ZendFramework", - "mime", - "zf" - ], - "time": "2017-11-28T15:02:22+00:00" - }, - { - "name": "zendframework/zend-modulemanager", - "version": "2.8.2", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-modulemanager.git", - "reference": "394df6e12248ac430a312d4693f793ee7120baa6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-modulemanager/zipball/394df6e12248ac430a312d4693f793ee7120baa6", - "reference": "394df6e12248ac430a312d4693f793ee7120baa6", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0", - "zendframework/zend-config": "^3.1 || ^2.6", - "zendframework/zend-eventmanager": "^3.2 || ^2.6.3", - "zendframework/zend-stdlib": "^3.1 || ^2.7" - }, - "require-dev": { - "phpunit/phpunit": "^6.0.8 || ^5.7.15", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-console": "^2.6", - "zendframework/zend-di": "^2.6", - "zendframework/zend-loader": "^2.5", - "zendframework/zend-mvc": "^3.0 || ^2.7", - "zendframework/zend-servicemanager": "^3.0.3 || ^2.7.5" - }, - "suggest": { - "zendframework/zend-console": "Zend\\Console component", - "zendframework/zend-loader": "Zend\\Loader component if you are not using Composer autoloading for your modules", - "zendframework/zend-mvc": "Zend\\Mvc component", - "zendframework/zend-servicemanager": "Zend\\ServiceManager component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\ModuleManager\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Modular application system for zend-mvc applications", - "homepage": "https://github.com/zendframework/zend-modulemanager", - "keywords": [ - "ZendFramework", - "modulemanager", - "zf" - ], - "time": "2017-12-02T06:11:18+00:00" - }, - { - "name": "zendframework/zend-mvc", - "version": "2.6.3", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-mvc.git", - "reference": "a0f21c0261adab4a27bd10964995625b7d4c7f64" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-mvc/zipball/a0f21c0261adab4a27bd10964995625b7d4c7f64", - "reference": "a0f21c0261adab4a27bd10964995625b7d4c7f64", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "zendframework/zend-eventmanager": "~2.5", - "zendframework/zend-form": "~2.6", - "zendframework/zend-hydrator": "~1.0", - "zendframework/zend-servicemanager": "~2.5", - "zendframework/zend-stdlib": "^2.7.5" - }, - "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0", - "zendframework/zend-authentication": "~2.5", - "zendframework/zend-cache": "~2.5", - "zendframework/zend-console": "~2.5", - "zendframework/zend-di": "~2.5", - "zendframework/zend-filter": "~2.5", - "zendframework/zend-http": "~2.5", - "zendframework/zend-i18n": "~2.5", - "zendframework/zend-inputfilter": "~2.5", - "zendframework/zend-json": "~2.5", - "zendframework/zend-log": "~2.5", - "zendframework/zend-modulemanager": "~2.6", - "zendframework/zend-serializer": "~2.5", - "zendframework/zend-session": "~2.5", - "zendframework/zend-text": "~2.5", - "zendframework/zend-uri": "~2.5", - "zendframework/zend-validator": "~2.5", - "zendframework/zend-version": "~2.5", - "zendframework/zend-view": "~2.5" - }, - "suggest": { - "zendframework/zend-authentication": "Zend\\Authentication component for Identity plugin", - "zendframework/zend-config": "Zend\\Config component", - "zendframework/zend-console": "Zend\\Console component", - "zendframework/zend-di": "Zend\\Di component", - "zendframework/zend-filter": "Zend\\Filter component", - "zendframework/zend-http": "Zend\\Http component", - "zendframework/zend-i18n": "Zend\\I18n component for translatable segments", - "zendframework/zend-inputfilter": "Zend\\Inputfilter component", - "zendframework/zend-json": "Zend\\Json component", - "zendframework/zend-log": "Zend\\Log component", - "zendframework/zend-modulemanager": "Zend\\ModuleManager component", - "zendframework/zend-serializer": "Zend\\Serializer component", - "zendframework/zend-session": "Zend\\Session component for FlashMessenger, PRG, and FPRG plugins", - "zendframework/zend-text": "Zend\\Text component", - "zendframework/zend-uri": "Zend\\Uri component", - "zendframework/zend-validator": "Zend\\Validator component", - "zendframework/zend-version": "Zend\\Version component", - "zendframework/zend-view": "Zend\\View component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev", - "dev-develop": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Mvc\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-mvc", - "keywords": [ - "mvc", - "zf2" - ], - "time": "2016-02-23T15:24:59+00:00" - }, - { - "name": "zendframework/zend-serializer", - "version": "2.8.1", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-serializer.git", - "reference": "7ac42b9a47e9cb23895173a3096bc3b3fb7ac580" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-serializer/zipball/7ac42b9a47e9cb23895173a3096bc3b3fb7ac580", - "reference": "7ac42b9a47e9cb23895173a3096bc3b3fb7ac580", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0", - "zendframework/zend-json": "^2.5 || ^3.0", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "require-dev": { - "doctrine/instantiator": "1.0.*", - "phpunit/phpunit": "^5.5", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-math": "^2.6", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3" - }, - "suggest": { - "zendframework/zend-math": "(^2.6 || ^3.0) To support Python Pickle serialization", - "zendframework/zend-servicemanager": "(^2.7.5 || ^3.0.3) To support plugin manager support" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev", - "dev-develop": "2.9-dev" - }, - "zf": { - "component": "Zend\\Serializer", - "config-provider": "Zend\\Serializer\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Zend\\Serializer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides an adapter based interface to simply generate storable representation of PHP types by different facilities, and recover", - "homepage": "https://github.com/zendframework/zend-serializer", - "keywords": [ - "serializer", - "zf2" - ], - "time": "2017-11-20T22:21:04+00:00" - }, - { - "name": "zendframework/zend-server", - "version": "2.7.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-server.git", - "reference": "7cb617ca3e9b24579f544a244ee79ae61f480914" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-server/zipball/7cb617ca3e9b24579f544a244ee79ae61f480914", - "reference": "7cb617ca3e9b24579f544a244ee79ae61f480914", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0", - "zendframework/zend-code": "^2.5 || ^3.0", - "zendframework/zend-stdlib": "^2.5 || ^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8", - "squizlabs/php_codesniffer": "^2.3.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Server\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-server", - "keywords": [ - "server", - "zf2" - ], - "time": "2016-06-20T22:27:55+00:00" - }, - { - "name": "zendframework/zend-servicemanager", - "version": "2.7.10", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-servicemanager.git", - "reference": "ba7069c94c9af93122be9fa31cddd37f7707d5b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-servicemanager/zipball/ba7069c94c9af93122be9fa31cddd37f7707d5b4", - "reference": "ba7069c94c9af93122be9fa31cddd37f7707d5b4", - "shasum": "" - }, - "require": { - "container-interop/container-interop": "~1.0", - "php": "^5.5 || ^7.0" - }, - "require-dev": { - "athletic/athletic": "dev-master", - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0", - "zendframework/zend-di": "~2.5", - "zendframework/zend-mvc": "~2.5" - }, - "suggest": { - "ocramius/proxy-manager": "ProxyManager 0.5.* to handle lazy initialization of services", - "zendframework/zend-di": "Zend\\Di component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\ServiceManager\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-servicemanager", - "keywords": [ - "servicemanager", - "zf2" - ], - "time": "2017-12-05T16:27:36+00:00" - }, - { - "name": "zendframework/zend-session", - "version": "2.8.4", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-session.git", - "reference": "9338f1ae483bcc18cc3b6c0347c8ba4f448b3e2a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-session/zipball/9338f1ae483bcc18cc3b6c0347c8ba4f448b3e2a", - "reference": "9338f1ae483bcc18cc3b6c0347c8ba4f448b3e2a", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0", - "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "conflict": { - "phpunit/phpunit": ">=6.5.0" - }, - "require-dev": { - "container-interop/container-interop": "^1.1", - "mongodb/mongodb": "^1.0.1", - "php-mock/php-mock-phpunit": "^1.1.2 || ^2.0", - "phpunit/phpunit": "^5.7.5 || ^6.0.13", - "zendframework/zend-cache": "^2.6.1", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-db": "^2.7", - "zendframework/zend-http": "^2.5.4", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", - "zendframework/zend-validator": "^2.6" - }, - "suggest": { - "mongodb/mongodb": "If you want to use the MongoDB session save handler", - "zendframework/zend-cache": "Zend\\Cache component", - "zendframework/zend-db": "Zend\\Db component", - "zendframework/zend-http": "Zend\\Http component", - "zendframework/zend-servicemanager": "Zend\\ServiceManager component", - "zendframework/zend-validator": "Zend\\Validator component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev", - "dev-develop": "2.9-dev" - }, - "zf": { - "component": "Zend\\Session", - "config-provider": "Zend\\Session\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Zend\\Session\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "manage and preserve session data, a logical complement of cookie data, across multiple page requests by the same client", - "keywords": [ - "ZendFramework", - "session", - "zf" - ], - "time": "2018-01-31T17:38:47+00:00" - }, - { - "name": "zendframework/zend-soap", - "version": "2.7.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-soap.git", - "reference": "af03c32f0db2b899b3df8cfe29aeb2b49857d284" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-soap/zipball/af03c32f0db2b899b3df8cfe29aeb2b49857d284", - "reference": "af03c32f0db2b899b3df8cfe29aeb2b49857d284", - "shasum": "" - }, - "require": { - "ext-soap": "*", - "php": "^5.6 || ^7.0", - "zendframework/zend-server": "^2.6.1", - "zendframework/zend-stdlib": "^2.7 || ^3.0", - "zendframework/zend-uri": "^2.5.2" - }, - "require-dev": { - "phpunit/phpunit": "^5.7.21 || ^6.3", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-config": "^2.6", - "zendframework/zend-http": "^2.5.4" - }, - "suggest": { - "zendframework/zend-http": "Zend\\Http component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7.x-dev", - "dev-develop": "2.8.x-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Soap\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-soap", - "keywords": [ - "soap", - "zf2" - ], - "time": "2018-01-29T17:51:26+00:00" - }, - { - "name": "zendframework/zend-stdlib", - "version": "2.7.7", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-stdlib.git", - "reference": "0e44eb46788f65e09e077eb7f44d2659143bcc1f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/0e44eb46788f65e09e077eb7f44d2659143bcc1f", - "reference": "0e44eb46788f65e09e077eb7f44d2659143bcc1f", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "zendframework/zend-hydrator": "~1.1" - }, - "require-dev": { - "athletic/athletic": "~0.1", - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0", - "zendframework/zend-config": "~2.5", - "zendframework/zend-eventmanager": "~2.5", - "zendframework/zend-filter": "~2.5", - "zendframework/zend-inputfilter": "~2.5", - "zendframework/zend-serializer": "~2.5", - "zendframework/zend-servicemanager": "~2.5" - }, - "suggest": { - "zendframework/zend-eventmanager": "To support aggregate hydrator usage", - "zendframework/zend-filter": "To support naming strategy hydrator usage", - "zendframework/zend-serializer": "Zend\\Serializer component", - "zendframework/zend-servicemanager": "To support hydrator plugin manager usage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-release-2.7": "2.7-dev", - "dev-master": "3.0-dev", - "dev-develop": "3.1-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Stdlib\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-stdlib", - "keywords": [ - "stdlib", - "zf2" - ], - "time": "2016-04-12T21:17:31+00:00" - }, - { - "name": "zendframework/zend-text", - "version": "2.6.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-text.git", - "reference": "07ad9388e4d4f12620ad37b52a5b0e4ee7845f92" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-text/zipball/07ad9388e4d4f12620ad37b52a5b0e4ee7845f92", - "reference": "07ad9388e4d4f12620ad37b52a5b0e4ee7845f92", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0", - "zendframework/zend-config": "^2.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev", - "dev-develop": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Text\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-text", - "keywords": [ - "text", - "zf2" - ], - "time": "2016-02-08T19:03:52+00:00" - }, - { - "name": "zendframework/zend-uri", - "version": "2.5.2", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-uri.git", - "reference": "0bf717a239432b1a1675ae314f7c4acd742749ed" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-uri/zipball/0bf717a239432b1a1675ae314f7c4acd742749ed", - "reference": "0bf717a239432b1a1675ae314f7c4acd742749ed", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "zendframework/zend-escaper": "^2.5", - "zendframework/zend-validator": "^2.5" - }, - "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Uri\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "a component that aids in manipulating and validating » Uniform Resource Identifiers (URIs)", - "homepage": "https://github.com/zendframework/zend-uri", - "keywords": [ - "uri", - "zf2" - ], - "time": "2016-02-17T22:38:51+00:00" - }, - { - "name": "zendframework/zend-validator", - "version": "2.10.2", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-validator.git", - "reference": "38109ed7d8e46cfa71bccbe7e6ca80cdd035f8c9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-validator/zipball/38109ed7d8e46cfa71bccbe7e6ca80cdd035f8c9", - "reference": "38109ed7d8e46cfa71bccbe7e6ca80cdd035f8c9", - "shasum": "" - }, - "require": { - "container-interop/container-interop": "^1.1", - "php": "^5.6 || ^7.0", - "zendframework/zend-stdlib": "^2.7.6 || ^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.0.8 || ^5.7.15", - "zendframework/zend-cache": "^2.6.1", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-config": "^2.6", - "zendframework/zend-db": "^2.7", - "zendframework/zend-filter": "^2.6", - "zendframework/zend-http": "^2.5.4", - "zendframework/zend-i18n": "^2.6", - "zendframework/zend-math": "^2.6", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", - "zendframework/zend-session": "^2.8", - "zendframework/zend-uri": "^2.5" - }, - "suggest": { - "zendframework/zend-db": "Zend\\Db component, required by the (No)RecordExists validator", - "zendframework/zend-filter": "Zend\\Filter component, required by the Digits validator", - "zendframework/zend-i18n": "Zend\\I18n component to allow translation of validation error messages", - "zendframework/zend-i18n-resources": "Translations of validator messages", - "zendframework/zend-math": "Zend\\Math component, required by the Csrf validator", - "zendframework/zend-servicemanager": "Zend\\ServiceManager component to allow using the ValidatorPluginManager and validator chains", - "zendframework/zend-session": "Zend\\Session component, ^2.8; required by the Csrf validator", - "zendframework/zend-uri": "Zend\\Uri component, required by the Uri and Sitemap\\Loc validators" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.10.x-dev", - "dev-develop": "2.11.x-dev" - }, - "zf": { - "component": "Zend\\Validator", - "config-provider": "Zend\\Validator\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Zend\\Validator\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides a set of commonly needed validators", - "homepage": "https://github.com/zendframework/zend-validator", - "keywords": [ - "validator", - "zf2" - ], - "time": "2018-02-01T17:05:33+00:00" - }, - { - "name": "zendframework/zend-view", - "version": "2.10.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-view.git", - "reference": "4478cc5dd960e2339d88b363ef99fa278700e80e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-view/zipball/4478cc5dd960e2339d88b363ef99fa278700e80e", - "reference": "4478cc5dd960e2339d88b363ef99fa278700e80e", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0", - "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", - "zendframework/zend-loader": "^2.5", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7.15 || ^6.0.8", - "zendframework/zend-authentication": "^2.5", - "zendframework/zend-cache": "^2.6.1", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-config": "^2.6", - "zendframework/zend-console": "^2.6", - "zendframework/zend-escaper": "^2.5", - "zendframework/zend-feed": "^2.7", - "zendframework/zend-filter": "^2.6.1", - "zendframework/zend-http": "^2.5.4", - "zendframework/zend-i18n": "^2.6", - "zendframework/zend-json": "^2.6.1", - "zendframework/zend-log": "^2.7", - "zendframework/zend-modulemanager": "^2.7.1", - "zendframework/zend-mvc": "^2.7 || ^3.0", - "zendframework/zend-navigation": "^2.5", - "zendframework/zend-paginator": "^2.5", - "zendframework/zend-permissions-acl": "^2.6", - "zendframework/zend-router": "^3.0.1", - "zendframework/zend-serializer": "^2.6.1", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", - "zendframework/zend-session": "^2.8.1", - "zendframework/zend-uri": "^2.5" - }, - "suggest": { - "zendframework/zend-authentication": "Zend\\Authentication component", - "zendframework/zend-escaper": "Zend\\Escaper component", - "zendframework/zend-feed": "Zend\\Feed component", - "zendframework/zend-filter": "Zend\\Filter component", - "zendframework/zend-http": "Zend\\Http component", - "zendframework/zend-i18n": "Zend\\I18n component", - "zendframework/zend-json": "Zend\\Json component", - "zendframework/zend-mvc": "Zend\\Mvc component", - "zendframework/zend-navigation": "Zend\\Navigation component", - "zendframework/zend-paginator": "Zend\\Paginator component", - "zendframework/zend-permissions-acl": "Zend\\Permissions\\Acl component", - "zendframework/zend-servicemanager": "Zend\\ServiceManager component", - "zendframework/zend-uri": "Zend\\Uri component" - }, - "bin": [ - "bin/templatemap_generator.php" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.10.x-dev", - "dev-develop": "2.11.x-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\View\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides a system of helpers, output filters, and variable escaping", - "homepage": "https://github.com/zendframework/zend-view", - "keywords": [ - "view", - "zf2" - ], - "time": "2018-01-17T22:21:50+00:00" - } - ], - "packages-dev": [ - { - "name": "doctrine/instantiator", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", - "shasum": "" - }, - "require": { - "php": ">=5.3,<8.0-DEV" - }, - "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2015-06-14T21:17:01+00:00" - }, - { - "name": "friendsofphp/php-cs-fixer", - "version": "v2.1.3", - "source": { - "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "d30ca69f8bed931b5c630407f0a98306e33c2c39" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/d30ca69f8bed931b5c630407f0a98306e33c2c39", - "reference": "d30ca69f8bed931b5c630407f0a98306e33c2c39", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^5.3.6 || >=7.0 <7.2", - "sebastian/diff": "^1.1", - "symfony/console": "^2.3 || ^3.0", - "symfony/event-dispatcher": "^2.1 || ^3.0", - "symfony/filesystem": "^2.4 || ^3.0", - "symfony/finder": "^2.2 || ^3.0", - "symfony/polyfill-php54": "^1.0", - "symfony/polyfill-php55": "^1.3", - "symfony/polyfill-php70": "^1.0", - "symfony/polyfill-xml": "^1.3", - "symfony/process": "^2.3 || ^3.0", - "symfony/stopwatch": "^2.5 || ^3.0" - }, - "conflict": { - "hhvm": "<3.9" - }, - "require-dev": { - "gecko-packages/gecko-php-unit": "^2.0", - "justinrainbow/json-schema": "^5.0", - "phpunit/phpunit": "^4.5 || ^5.0", - "satooshi/php-coveralls": "^1.0", - "symfony/phpunit-bridge": "^3.2" - }, - "suggest": { - "ext-mbstring": "For handling non-UTF8 characters in cache singature.", - "ext-xml": "For better performance.", - "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." - }, - "bin": [ - "php-cs-fixer" - ], - "type": "application", - "autoload": { - "psr-4": { - "PhpCsFixer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "A tool to automatically fix PHP code style", - "time": "2017-03-31T12:59:38+00:00" - }, - { - "name": "ircmaxell/password-compat", - "version": "v1.0.4", - "source": { - "type": "git", - "url": "https://github.com/ircmaxell/password_compat.git", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", - "shasum": "" - }, - "require-dev": { - "phpunit/phpunit": "4.*" - }, - "type": "library", - "autoload": { - "files": [ - "lib/password.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Anthony Ferrara", - "email": "ircmaxell@php.net", - "homepage": "http://blog.ircmaxell.com" - } - ], - "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", - "homepage": "https://github.com/ircmaxell/password_compat", - "keywords": [ - "hashing", - "password" - ], - "time": "2014-11-20T16:49:30+00:00" - }, - { - "name": "lusitanian/oauth", - "version": "v0.8.10", - "source": { - "type": "git", - "url": "https://github.com/Lusitanian/PHPoAuthLib.git", - "reference": "09f4af38f17db6938253f4d1b171d537913ac1ed" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Lusitanian/PHPoAuthLib/zipball/09f4af38f17db6938253f4d1b171d537913ac1ed", - "reference": "09f4af38f17db6938253f4d1b171d537913ac1ed", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "3.7.*", - "predis/predis": "0.8.*@dev", - "squizlabs/php_codesniffer": "2.*", - "symfony/http-foundation": "~2.1" - }, - "suggest": { - "ext-openssl": "Allows for usage of secure connections with the stream-based HTTP client.", - "predis/predis": "Allows using the Redis storage backend.", - "symfony/http-foundation": "Allows using the Symfony Session storage backend." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.1-dev" - } - }, - "autoload": { - "psr-0": { - "OAuth": "src", - "OAuth\\Unit": "tests" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "David Desberg", - "email": "david@daviddesberg.com" - }, - { - "name": "Elliot Chance", - "email": "elliotchance@gmail.com" - }, - { - "name": "Pieter Hordijk", - "email": "info@pieterhordijk.com" - } - ], - "description": "PHP 5.3+ oAuth 1/2 Library", - "keywords": [ - "Authentication", - "authorization", - "oauth", - "security" - ], - "time": "2016-07-12T22:15:40+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.7.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^4.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, - "files": [ - "src/DeepCopy/deep_copy.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "time": "2017-10-19T19:58:43+00:00" - }, - { - "name": "pdepend/pdepend", - "version": "2.5.0", - "source": { - "type": "git", - "url": "https://github.com/pdepend/pdepend.git", - "reference": "0c50874333149c0dad5a2877801aed148f2767ff" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pdepend/pdepend/zipball/0c50874333149c0dad5a2877801aed148f2767ff", - "reference": "0c50874333149c0dad5a2877801aed148f2767ff", - "shasum": "" - }, - "require": { - "php": ">=5.3.7", - "symfony/config": "^2.3.0|^3", - "symfony/dependency-injection": "^2.3.0|^3", - "symfony/filesystem": "^2.3.0|^3" - }, - "require-dev": { - "phpunit/phpunit": "^4.4.0,<4.8", - "squizlabs/php_codesniffer": "^2.0.0" - }, - "bin": [ - "src/bin/pdepend" - ], - "type": "library", - "autoload": { - "psr-4": { - "PDepend\\": "src/main/php/PDepend" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Official version of pdepend to be handled with Composer", - "time": "2017-01-19T14:23:36+00:00" - }, - { - "name": "phar-io/manifest", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "phar-io/version": "^1.0.1", - "php": "^5.6 || ^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" - }, - { - "name": "phar-io/version", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "^4.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "time": "2017-09-11T18:02:19+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "4.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08", - "shasum": "" - }, - "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", - "webmozart/assert": "^1.0" - }, - "require-dev": { - "doctrine/instantiator": "~1.0.5", - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-30T07:14:17+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" - }, - "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "time": "2017-07-14T14:27:02+00:00" - }, - { - "name": "phpmd/phpmd", - "version": "2.6.0", - "source": { - "type": "git", - "url": "https://github.com/phpmd/phpmd.git", - "reference": "4e9924b2c157a3eb64395460fcf56b31badc8374" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpmd/phpmd/zipball/4e9924b2c157a3eb64395460fcf56b31badc8374", - "reference": "4e9924b2c157a3eb64395460fcf56b31badc8374", - "shasum": "" - }, - "require": { - "ext-xml": "*", - "pdepend/pdepend": "^2.5", - "php": ">=5.3.9" - }, - "require-dev": { - "phpunit/phpunit": "^4.0", - "squizlabs/php_codesniffer": "^2.0" - }, - "bin": [ - "src/bin/phpmd" - ], - "type": "project", - "autoload": { - "psr-0": { - "PHPMD\\": "src/main/php" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Manuel Pichler", - "email": "github@manuel-pichler.de", - "homepage": "https://github.com/manuelpichler", - "role": "Project Founder" - }, - { - "name": "Other contributors", - "homepage": "https://github.com/phpmd/phpmd/graphs/contributors", - "role": "Contributors" - }, - { - "name": "Marc Würth", - "email": "ravage@bluewin.ch", - "homepage": "https://github.com/ravage84", - "role": "Project Maintainer" - } - ], - "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", - "homepage": "http://phpmd.org/", - "keywords": [ - "mess detection", - "mess detector", - "pdepend", - "phpmd", - "pmd" - ], - "time": "2017-01-20T14:41:10+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "1.7.3", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", - "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", - "sebastian/comparator": "^1.1|^2.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7.x-dev" - } - }, - "autoload": { - "psr-0": { - "Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2017-11-24T13:59:53+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "5.3.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/661f34d0bd3f1a7225ef491a70a020ad23a057a1", - "reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": "^7.0", - "phpunit/php-file-iterator": "^1.4.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^2.0.1", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.0", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-xdebug": "^2.5.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2017-12-06T09:29:45+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2017-11-27T13:52:08+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21T13:50:34+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.9", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2017-02-26T11:10:40+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "791198a2c6254db10131eecfe8c06670700904db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", - "reference": "791198a2c6254db10131eecfe8c06670700904db", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.2.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2017-11-27T05:48:46+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "6.2.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "ff3a76a58ac293657808aefd58c8aaf05945f4d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ff3a76a58ac293657808aefd58c8aaf05945f4d9", - "reference": "ff3a76a58ac293657808aefd58c8aaf05945f4d9", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "myclabs/deep-copy": "^1.3", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", - "php": "^7.0", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^5.2", - "phpunit/php-file-iterator": "^1.4", - "phpunit/php-text-template": "^1.2", - "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "^4.0", - "sebastian/comparator": "^2.0", - "sebastian/diff": "^1.4.3", - "sebastian/environment": "^3.0.2", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^1.1 || ^2.0", - "sebastian/object-enumerator": "^3.0.2", - "sebastian/resource-operations": "^1.0", - "sebastian/version": "^2.0" - }, - "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2", - "phpunit/dbunit": "<3.0" - }, - "require-dev": { - "ext-pdo": "*" - }, - "suggest": { - "ext-xdebug": "*", - "phpunit/php-invoker": "^1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2017-08-03T13:59:28+00:00" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "2f789b59ab89669015ad984afa350c4ec577ade0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/2f789b59ab89669015ad984afa350c4ec577ade0", - "reference": "2f789b59ab89669015ad984afa350c4ec577ade0", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.5", - "php": "^7.0", - "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.0" - }, - "conflict": { - "phpunit/phpunit": "<6.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2017-08-03T14:08:16+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" - }, - { - "name": "sebastian/comparator", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "20f84f468cb67efee293246e6a09619b891f55f0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/20f84f468cb67efee293246e6a09619b891f55f0", - "reference": "20f84f468cb67efee293246e6a09619b891f55f0", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/diff": "^1.2", - "sebastian/exporter": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2017-03-03T06:26:08+00:00" - }, - { - "name": "sebastian/diff", - "version": "1.4.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "time": "2017-05-22T07:24:03+00:00" - }, - { - "name": "sebastian/environment", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "time": "2017-07-01T08:51:00+00:00" - }, - { - "name": "sebastian/exporter", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2017-04-03T13:19:02+00:00" - }, - { - "name": "sebastian/finder-facade", - "version": "1.2.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/finder-facade.git", - "reference": "4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f", - "reference": "4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f", - "shasum": "" - }, - "require": { - "symfony/finder": "~2.3|~3.0|~4.0", - "theseer/fdomdocument": "~1.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", - "homepage": "https://github.com/sebastianbergmann/finder-facade", - "time": "2017-11-18T17:31:49+00:00" - }, - { - "name": "sebastian/global-state", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "time": "2017-04-27T15:39:26+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" - }, - { - "name": "sebastian/phpcpd", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpcpd.git", - "reference": "24d9a880deadb0b8c9680e9cfe78e30b704225db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/24d9a880deadb0b8c9680e9cfe78e30b704225db", - "reference": "24d9a880deadb0b8c9680e9cfe78e30b704225db", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-timer": ">=1.0.6", - "sebastian/finder-facade": "~1.1", - "sebastian/version": "~1.0|~2.0", - "symfony/console": "~2.7|^3.0", - "theseer/fdomdocument": "~1.4" - }, - "bin": [ - "phpcpd" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Copy/Paste Detector (CPD) for PHP code.", - "homepage": "https://github.com/sebastianbergmann/phpcpd", - "time": "2016-04-17T19:32:49+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "shasum": "" - }, - "require": { - "php": ">=5.6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" - }, - { - "name": "sebastian/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "f9eaf037edf22fdfccf04cb0ab57ebcb1e166219" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/f9eaf037edf22fdfccf04cb0ab57ebcb1e166219", - "reference": "f9eaf037edf22fdfccf04cb0ab57ebcb1e166219", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "http://www.squizlabs.com/php-codesniffer", - "keywords": [ - "phpcs", - "standards" - ], - "time": "2017-06-14T01:23:49+00:00" - }, - { - "name": "symfony/config", - "version": "v3.4.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/config.git", - "reference": "72689b934d6c6ecf73eca874e98933bf055313c9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/72689b934d6c6ecf73eca874e98933bf055313c9", - "reference": "72689b934d6c6ecf73eca874e98933bf055313c9", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/filesystem": "~2.8|~3.0|~4.0" - }, - "conflict": { - "symfony/dependency-injection": "<3.3", - "symfony/finder": "<3.3" - }, - "require-dev": { - "symfony/dependency-injection": "~3.3|~4.0", - "symfony/finder": "~3.3|~4.0", - "symfony/yaml": "~3.0|~4.0" - }, - "suggest": { - "symfony/yaml": "To use the yaml reference dumper" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Config\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Config Component", - "homepage": "https://symfony.com", - "time": "2018-01-21T19:05:02+00:00" - }, - { - "name": "symfony/dependency-injection", - "version": "v3.4.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/dependency-injection.git", - "reference": "4b2717ee2499390e371e1fc7abaf886c1c83e83d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/4b2717ee2499390e371e1fc7abaf886c1c83e83d", - "reference": "4b2717ee2499390e371e1fc7abaf886c1c83e83d", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8", - "psr/container": "^1.0" - }, - "conflict": { - "symfony/config": "<3.3.7", - "symfony/finder": "<3.3", - "symfony/proxy-manager-bridge": "<3.4", - "symfony/yaml": "<3.4" - }, - "provide": { - "psr/container-implementation": "1.0" - }, - "require-dev": { - "symfony/config": "~3.3|~4.0", - "symfony/expression-language": "~2.8|~3.0|~4.0", - "symfony/yaml": "~3.4|~4.0" - }, - "suggest": { - "symfony/config": "", - "symfony/expression-language": "For using expressions in service container configuration", - "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", - "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\DependencyInjection\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony DependencyInjection Component", - "homepage": "https://symfony.com", - "time": "2018-01-29T09:16:57+00:00" - }, - { - "name": "symfony/polyfill-php54", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php54.git", - "reference": "84e2b616c197ef400c6d0556a0606cee7c9e21d5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/84e2b616c197ef400c6d0556a0606cee7c9e21d5", - "reference": "84e2b616c197ef400c6d0556a0606cee7c9e21d5", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php54\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-30T19:27:44+00:00" - }, - { - "name": "symfony/polyfill-php55", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php55.git", - "reference": "168371cb3dfb10e0afde96e7c2688be02470d143" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/168371cb3dfb10e0afde96e7c2688be02470d143", - "reference": "168371cb3dfb10e0afde96e7c2688be02470d143", - "shasum": "" - }, - "require": { - "ircmaxell/password-compat": "~1.0", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php55\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-30T19:27:44+00:00" - }, - { - "name": "symfony/polyfill-php70", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3532bfcd8f933a7816f3a0a59682fc404776600f", - "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f", - "shasum": "" - }, - "require": { - "paragonie/random_compat": "~1.0|~2.0", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php70\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-30T19:27:44+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "8eca20c8a369e069d4f4c2ac9895144112867422" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/8eca20c8a369e069d4f4c2ac9895144112867422", - "reference": "8eca20c8a369e069d4f4c2ac9895144112867422", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-31T17:43:24+00:00" - }, - { - "name": "symfony/polyfill-xml", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-xml.git", - "reference": "fcdfb6e64d21848ee65b6d5d0bc75fcb703b0c83" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-xml/zipball/fcdfb6e64d21848ee65b6d5d0bc75fcb703b0c83", - "reference": "fcdfb6e64d21848ee65b6d5d0bc75fcb703b0c83", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/polyfill-php72": "~1.4" - }, - "type": "metapackage", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for xml's utf8_encode and utf8_decode functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-30T19:27:44+00:00" - }, - { - "name": "symfony/stopwatch", - "version": "v3.4.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "c865551df7c17e63fc1f09f763db04387f91ae4d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/c865551df7c17e63fc1f09f763db04387f91ae4d", - "reference": "c865551df7c17e63fc1f09f763db04387f91ae4d", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Stopwatch Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "theseer/fdomdocument", - "version": "1.6.6", - "source": { - "type": "git", - "url": "https://github.com/theseer/fDOMDocument.git", - "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/6e8203e40a32a9c770bcb62fe37e68b948da6dca", - "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "lib-libxml": "*", - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "lead" - } - ], - "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", - "homepage": "https://github.com/theseer/fDOMDocument", - "time": "2017-06-30T11:53:12+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2017-04-07T12:08:54+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "0df1908962e7a3071564e857d86874dad1ef204a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", - "reference": "0df1908962e7a3071564e857d86874dad1ef204a", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "time": "2018-01-29T19:49:41+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "phpmd/phpmd": 0 - }, - "prefer-stable": true, - "prefer-lowest": false, - "platform": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", - "ext-ctype": "*", - "ext-curl": "*", - "ext-dom": "*", - "ext-gd": "*", - "ext-hash": "*", - "ext-iconv": "*", - "ext-intl": "*", - "ext-mbstring": "*", - "ext-mcrypt": "*", - "ext-openssl": "*", - "ext-pdo_mysql": "*", - "ext-simplexml": "*", - "ext-soap": "*", - "ext-spl": "*", - "ext-xsl": "*", - "ext-zip": "*", - "lib-libxml": "*" - }, - "platform-dev": [] -} From 19b0c89f64b1b449fd2dc471f67e65cbc2d4092a Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <dhorytskyi@magento.com> Date: Wed, 28 Feb 2018 17:37:31 +0200 Subject: [PATCH 030/668] MAGETWO-72863: Attribute values on store view level not searchable --- .../Indexer/Fulltext/Action/DataProvider.php | 36 ++++++++++------ .../Fulltext/Action/DataProviderTest.php | 41 +++++++++++++++++++ .../_files/product_for_search.php | 23 +++++++++++ .../_files/product_for_search_rollback.php | 26 ++++++++++++ .../_files/searchable_attribute.php | 26 ++++++++++++ 5 files changed, 140 insertions(+), 12 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProviderTest.php create mode 100644 dev/tests/integration/testsuite/Magento/CatalogSearch/_files/product_for_search.php create mode 100644 dev/tests/integration/testsuite/Magento/CatalogSearch/_files/product_for_search_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/CatalogSearch/_files/searchable_attribute.php diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php index 708f8b9163a38..059d78f8721e3 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -307,28 +307,40 @@ public function getProductAttributes($storeId, array $productIds, array $attribu foreach ($attributeTypes as $backendType => $attributeIds) { if ($attributeIds) { $tableName = $this->getTable('catalog_product_entity_' . $backendType); - $selects[] = $this->connection->select()->from( - ['t_default' => $tableName], - [$linkField, 'attribute_id'] + + $select = $this->connection->select()->from( + ['t' => $tableName], + [ + $linkField => 't.' . $linkField, + 'attribute_id' => 't.attribute_id', + 'value' => $this->unifyField($ifStoreValue, $backendType), + ] )->joinLeft( ['t_store' => $tableName], $this->connection->quoteInto( - 't_default.' . $linkField . '=t_store.' . $linkField . - ' AND t_default.attribute_id=t_store.attribute_id' . + 't.' . $linkField . '=t_store.' . $linkField . + ' AND t.attribute_id=t_store.attribute_id' . ' AND t_store.store_id = ?', $storeId ), - ['value' => $this->unifyField($ifStoreValue, $backendType)] - )->where( - 't_default.store_id = ?', - 0 + [] + )->joinLeft( + ['t_default' => $tableName], + $this->connection->quoteInto( + 't.' . $linkField . '=t_default.' . $linkField . + ' AND t.attribute_id=t_default.attribute_id' . + ' AND t_default.store_id = ?', + 0 + ), + [] )->where( - 't_default.attribute_id IN (?)', + 't.attribute_id IN (?)', $attributeIds )->where( - 't_default.' . $linkField . ' IN (?)', + 't.' . $linkField . ' IN (?)', array_keys($productLinkFieldsToEntityIdMap) - ); + )->distinct(); + $selects[] = $select; } } diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProviderTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProviderTest.php new file mode 100644 index 0000000000000..0408efc28c9a1 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProviderTest.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogSearch\Model\Indexer\Fulltext\Action; + +class DataProviderTest extends \PHPUnit\Framework\TestCase +{ + /** + * @magentoDataFixture Magento/CatalogSearch/_files/product_for_search.php + * @magentoDbIsolation disabled + */ + public function testSearchProductByAttribute() + { + /** @var $objectManager \Magento\TestFramework\ObjectManager */ + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + + $config = $objectManager->create(\Magento\Framework\Search\Request\Config::class); + /** @var \Magento\Framework\Search\Request\Builder $requestBuilder */ + $requestBuilder = $objectManager->create( + \Magento\Framework\Search\Request\Builder::class, + ['config' => $config] + ); + $requestBuilder->bind('search_term', 'VALUE1'); + $requestBuilder->setRequestName('quick_search_container'); + $queryRequest = $requestBuilder->create(); + /** @var \Magento\Framework\Search\Adapter\Mysql\Adapter $adapter */ + $adapter = $objectManager->create(\Magento\Framework\Search\Adapter\Mysql\Adapter::class); + $queryResponse = $adapter->query($queryRequest); + $actualIds = []; + foreach ($queryResponse as $document) { + /** @var \Magento\Framework\Api\Search\Document $document */ + $actualIds[] = $document->getId(); + } + + /** @var \Magento\Catalog\Model\Product $product */ + $product = $objectManager->create(\Magento\Catalog\Model\ProductRepository::class)->get('simple'); + $this->assertContains($product->getId(), $actualIds, 'Product not found by searchable attribute.'); + } +} diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/_files/product_for_search.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/_files/product_for_search.php new file mode 100644 index 0000000000000..2d19b88ee10cd --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/_files/product_for_search.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require 'searchable_attribute.php'; +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple.php'; + +/** @var $objectManager \Magento\TestFramework\ObjectManager */ +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var \Magento\Store\Model\StoreManager $storeManager */ +$storeManager = $objectManager->get(\Magento\Store\Model\StoreManager::class); +$storeManager->setIsSingleStoreModeAllowed(false); +/** @var \Magento\Store\Model\Store $store */ +$store = $storeManager->getStore('default'); + +/** @var \Magento\Catalog\Model\Product $product */ +$product = $objectManager->create(\Magento\Catalog\Model\ProductRepository::class)->get('simple'); +/** @var \Magento\Catalog\Model\Product\Action $productAction */ +$productAction = $objectManager->create(\Magento\Catalog\Model\Product\Action::class); +$productAction->updateAttributes([$product->getId()], ['test_searchable_attribute' => 'VALUE1'], $store->getId()); diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/_files/product_for_search_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/_files/product_for_search_rollback.php new file mode 100644 index 0000000000000..09ddd7f957b9b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/_files/product_for_search_rollback.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var $objectManager \Magento\TestFramework\ObjectManager */ +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +$registry = $objectManager->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Model\Product $product */ +$product = $objectManager->create(\Magento\Catalog\Model\ProductRepository::class)->get('simple'); +/** @var \Magento\Catalog\Model\ResourceModel\Product $productResource */ +$productResource = $objectManager->create(\Magento\Catalog\Model\ResourceModel\Product::class); +$productResource->delete($product); + +$eavSetupFactory = $objectManager->create(\Magento\Eav\Setup\EavSetupFactory::class); +/** @var \Magento\Eav\Setup\EavSetup $eavSetup */ +$eavSetup = $eavSetupFactory->create(); +$eavSetup->removeAttribute(\Magento\Catalog\Model\Product::ENTITY, 'test_searchable_attribute'); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/_files/searchable_attribute.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/_files/searchable_attribute.php new file mode 100644 index 0000000000000..94082c562c614 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/_files/searchable_attribute.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +$eavSetupFactory = $objectManager->create(\Magento\Eav\Setup\EavSetupFactory::class); +/** @var \Magento\Eav\Setup\EavSetup $eavSetup */ +$eavSetup = $eavSetupFactory->create(); +$eavSetup->addAttribute( + \Magento\Catalog\Model\Product::ENTITY, + 'test_searchable_attribute', + [ + 'label' => 'Test-attribute', + 'global' => \Magento\Catalog\Model\ResourceModel\Eav\Attribute::SCOPE_STORE, + 'required' => 0, + 'user_defined' => 1, + 'searchable' => 1, + 'visible_on_front' => 1, + 'filterable_in_search' => 1, + 'used_in_product_listing' => 1, + 'is_used_in_grid' => 1, + 'is_filterable_in_grid' => 1, + ] +); From 193f30425279b60862a7d8dc574c84fcb73aca23 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <dhorytskyi@magento.com> Date: Thu, 28 Sep 2017 18:03:43 +0300 Subject: [PATCH 031/668] MAGETWO-72861: Category edit performance issue - for 2.3 --- app/code/Magento/Catalog/Model/Category.php | 2 + .../Category/Product/PositionResolver.php | 59 +++++++++ .../Catalog/Model/ResourceModel/Category.php | 15 ++- .../Category/Product/PositionResolverTest.php | 120 ++++++++++++++++++ .../Model/Indexer/IndexBuilder.php | 94 ++++++++------ .../Indexer/IndexBuilder/ProductLoader.php | 53 ++++++++ .../CatalogRule/Plugin/Indexer/Category.php | 2 +- .../IndexBuilder/ProductLoaderTest.php | 96 ++++++++++++++ .../Unit/Model/Indexer/IndexBuilderTest.php | 53 ++++++-- ...ategoryProcessUrlRewriteSavingObserver.php | 2 +- .../Observer/UrlRewriteHandler.php | 4 +- .../Unit/Observer/UrlRewriteHandlerTest.php | 2 +- 12 files changed, 441 insertions(+), 61 deletions(-) create mode 100644 app/code/Magento/Catalog/Model/Category/Product/PositionResolver.php create mode 100644 app/code/Magento/Catalog/Test/Unit/Model/Category/Product/PositionResolverTest.php create mode 100644 app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder/ProductLoader.php create mode 100644 app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilder/ProductLoaderTest.php diff --git a/app/code/Magento/Catalog/Model/Category.php b/app/code/Magento/Catalog/Model/Category.php index 69340665b2ca1..f659a95397503 100644 --- a/app/code/Magento/Catalog/Model/Category.php +++ b/app/code/Magento/Catalog/Model/Category.php @@ -32,6 +32,8 @@ * @method Category setUrlPath(string $urlPath) * @method Category getSkipDeleteChildren() * @method Category setSkipDeleteChildren(boolean $value) + * @method Category setChangedProductIds(array $categoryIds) Set products ids that inserted or deleted for category + * @method array getChangedProductIds() Get products ids that inserted or deleted for category * * @SuppressWarnings(PHPMD.LongVariable) * @SuppressWarnings(PHPMD.ExcessivePublicCount) diff --git a/app/code/Magento/Catalog/Model/Category/Product/PositionResolver.php b/app/code/Magento/Catalog/Model/Category/Product/PositionResolver.php new file mode 100644 index 0000000000000..97941f2d23b9f --- /dev/null +++ b/app/code/Magento/Catalog/Model/Category/Product/PositionResolver.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Model\Category\Product; + +/** + * Resolver to get product positions by ids assigned to specific category + */ +class PositionResolver extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb +{ + /** + * @param \Magento\Framework\Model\ResourceModel\Db\Context $context + * @param string $connectionName + */ + public function __construct( + \Magento\Framework\Model\ResourceModel\Db\Context $context, + $connectionName = null + ) { + parent::__construct($context, $connectionName); + } + + /** + * Initialize resource model + * + * @return void + */ + protected function _construct() + { + $this->_init('catalog_product_entity', 'entity_id'); + } + + /** + * Get category product positions + * + * @param int $categoryId + * @return array + */ + public function getPositions(int $categoryId) + { + $connection = $this->getConnection(); + + $select = $connection->select()->from( + ['cpe' => $this->getTable('catalog_product_entity')], + 'entity_id' + )->joinLeft( + ['ccp' => $this->getTable('catalog_category_product')], + 'ccp.product_id=cpe.entity_id' + )->where( + 'ccp.category_id = ?', + $categoryId + )->order( + 'ccp.position ' . \Magento\Framework\DB\Select::SQL_ASC + ); + + return array_flip($connection->fetchCol($select)); + } +} diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Category.php b/app/code/Magento/Catalog/Model/ResourceModel/Category.php index a9c705697b268..6c9867359d40b 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Category.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Category.php @@ -410,9 +410,18 @@ protected function _saveCategoryProducts($category) * Update product positions in category */ if (!empty($update)) { + $newPositions = []; foreach ($update as $productId => $position) { - $where = ['category_id = ?' => (int)$id, 'product_id = ?' => (int)$productId]; - $bind = ['position' => (int)$position]; + $delta = $position - $oldProducts[$productId]; + if (!isset($newPositions[$delta])) { + $newPositions[$delta] = []; + } + $newPositions[$delta][] = $productId; + } + + foreach ($newPositions as $delta => $productIds) { + $bind = ['position' => new \Zend_Db_Expr("position + ({$delta})")]; + $where = ['category_id = ?' => (int)$id, 'product_id IN (?)' => $productIds]; $connection->update($this->getCategoryProductTable(), $bind, $where); } } @@ -423,6 +432,8 @@ protected function _saveCategoryProducts($category) 'catalog_category_change_products', ['category' => $category, 'product_ids' => $productIds] ); + + $category->setChangedProductIds($productIds); } if (!empty($insert) || !empty($update) || !empty($delete)) { diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Category/Product/PositionResolverTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Category/Product/PositionResolverTest.php new file mode 100644 index 0000000000000..9545e5eb4b37d --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Model/Category/Product/PositionResolverTest.php @@ -0,0 +1,120 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Test\Unit\Model\Category\Product; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Catalog\Model\Category\Product\PositionResolver; +use Magento\Framework\Model\ResourceModel\Db\Context; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\DB\Select; + +class PositionResolverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var Context|\PHPUnit_Framework_MockObject_MockObject + */ + private $context; + + /** + * @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject + */ + private $resources; + + /** + * @var AdapterInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $connection; + + /** + * @var Select|\PHPUnit_Framework_MockObject_MockObject + */ + private $select; + + /** + * @var PositionResolver + */ + private $model; + + /** + * @var array + */ + private $positions = [ + '3' => 100, + '2' => 101, + '1' => 102 + ]; + + /** + * @var array + */ + private $flippedPositions = [ + '100' => 3, + '101' => 2, + '102' => 1 + ]; + + /** + * @var int + */ + private $categoryId = 1; + + protected function setUp() + { + $this->context = $this->getMockBuilder(Context::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->resources = $this->getMockBuilder(ResourceConnection::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->connection = $this->getMockBuilder(AdapterInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->select = $this->getMockBuilder(Select::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->model = (new ObjectManager($this))->getObject( + PositionResolver::class, + [ + 'context' => $this->context, + null, + '_resources' => $this->resources + ] + ); + } + + public function testGetPositions() + { + $this->resources->expects($this->once()) + ->method('getConnection') + ->willReturn($this->connection); + + $this->connection->expects($this->once()) + ->method('select') + ->willReturn($this->select); + $this->select->expects($this->once()) + ->method('from') + ->willReturnSelf(); + $this->select->expects($this->once()) + ->method('where') + ->willReturnSelf(); + $this->select->expects($this->once()) + ->method('order') + ->willReturnSelf(); + $this->select->expects($this->once()) + ->method('joinLeft') + ->willReturnSelf(); + $this->connection->expects($this->once()) + ->method('fetchCol') + ->willReturn($this->positions); + + $this->assertEquals($this->flippedPositions, $this->model->getPositions($this->categoryId)); + } +} diff --git a/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php b/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php index 34b4bff5a060e..f2dd8968a903d 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php @@ -11,6 +11,7 @@ use Magento\CatalogRule\Model\Rule; use Magento\Framework\App\ObjectManager; use Magento\Framework\Pricing\PriceCurrencyInterface; +use Magento\CatalogRule\Model\Indexer\IndexBuilder\ProductLoader; /** * @api @@ -101,32 +102,32 @@ class IndexBuilder protected $connection; /** - * @var \Magento\CatalogRule\Model\Indexer\ProductPriceCalculator + * @var ProductPriceCalculator */ private $productPriceCalculator; /** - * @var \Magento\CatalogRule\Model\Indexer\ReindexRuleProduct + * @var ReindexRuleProduct */ private $reindexRuleProduct; /** - * @var \Magento\CatalogRule\Model\Indexer\ReindexRuleGroupWebsite + * @var ReindexRuleGroupWebsite */ private $reindexRuleGroupWebsite; /** - * @var \Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder + * @var RuleProductsSelectBuilder */ private $ruleProductsSelectBuilder; /** - * @var \Magento\CatalogRule\Model\Indexer\ReindexRuleProductPrice + * @var ReindexRuleProductPrice */ private $reindexRuleProductPrice; /** - * @var \Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor + * @var RuleProductPricesPersistor */ private $pricesPersistor; @@ -135,6 +136,11 @@ class IndexBuilder */ private $activeTableSwitcher; + /** + * @var ProductLoader + */ + private $productLoader; + /** * @param RuleCollectionFactory $ruleCollectionFactory * @param PriceCurrencyInterface $priceCurrency @@ -146,13 +152,14 @@ class IndexBuilder * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime * @param \Magento\Catalog\Model\ProductFactory $productFactory * @param int $batchCount - * @param \Magento\CatalogRule\Model\Indexer\ProductPriceCalculator|null $productPriceCalculator - * @param \Magento\CatalogRule\Model\Indexer\ReindexRuleProduct|null $reindexRuleProduct - * @param \Magento\CatalogRule\Model\Indexer\ReindexRuleGroupWebsite|null $reindexRuleGroupWebsite - * @param \Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder|null $ruleProductsSelectBuilder - * @param \Magento\CatalogRule\Model\Indexer\ReindexRuleProductPrice|null $reindexRuleProductPrice - * @param \Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor|null $pricesPersistor + * @param ProductPriceCalculator|null $productPriceCalculator + * @param ReindexRuleProduct|null $reindexRuleProduct + * @param ReindexRuleGroupWebsite|null $reindexRuleGroupWebsite + * @param RuleProductsSelectBuilder|null $ruleProductsSelectBuilder + * @param ReindexRuleProductPrice|null $reindexRuleProductPrice + * @param RuleProductPricesPersistor|null $pricesPersistor * @param \Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher|null $activeTableSwitcher + * @param ProductLoader|null $productLoader * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -166,13 +173,14 @@ public function __construct( \Magento\Framework\Stdlib\DateTime\DateTime $dateTime, \Magento\Catalog\Model\ProductFactory $productFactory, $batchCount = 1000, - \Magento\CatalogRule\Model\Indexer\ProductPriceCalculator $productPriceCalculator = null, - \Magento\CatalogRule\Model\Indexer\ReindexRuleProduct $reindexRuleProduct = null, - \Magento\CatalogRule\Model\Indexer\ReindexRuleGroupWebsite $reindexRuleGroupWebsite = null, - \Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder $ruleProductsSelectBuilder = null, - \Magento\CatalogRule\Model\Indexer\ReindexRuleProductPrice $reindexRuleProductPrice = null, - \Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor $pricesPersistor = null, - \Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher $activeTableSwitcher = null + ProductPriceCalculator $productPriceCalculator = null, + ReindexRuleProduct $reindexRuleProduct = null, + ReindexRuleGroupWebsite $reindexRuleGroupWebsite = null, + RuleProductsSelectBuilder $ruleProductsSelectBuilder = null, + ReindexRuleProductPrice $reindexRuleProductPrice = null, + RuleProductPricesPersistor $pricesPersistor = null, + \Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher $activeTableSwitcher = null, + ProductLoader $productLoader = null ) { $this->resource = $resource; $this->connection = $resource->getConnection(); @@ -186,27 +194,30 @@ public function __construct( $this->productFactory = $productFactory; $this->batchCount = $batchCount; - $this->productPriceCalculator = $productPriceCalculator ?: ObjectManager::getInstance()->get( - \Magento\CatalogRule\Model\Indexer\ProductPriceCalculator::class + $this->productPriceCalculator = $productPriceCalculator ?? ObjectManager::getInstance()->get( + ProductPriceCalculator::class ); - $this->reindexRuleProduct = $reindexRuleProduct ?: ObjectManager::getInstance()->get( - \Magento\CatalogRule\Model\Indexer\ReindexRuleProduct::class + $this->reindexRuleProduct = $reindexRuleProduct ?? ObjectManager::getInstance()->get( + ReindexRuleProduct::class ); - $this->reindexRuleGroupWebsite = $reindexRuleGroupWebsite ?: ObjectManager::getInstance()->get( - \Magento\CatalogRule\Model\Indexer\ReindexRuleGroupWebsite::class + $this->reindexRuleGroupWebsite = $reindexRuleGroupWebsite ?? ObjectManager::getInstance()->get( + ReindexRuleGroupWebsite::class ); - $this->ruleProductsSelectBuilder = $ruleProductsSelectBuilder ?: ObjectManager::getInstance()->get( - \Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder::class + $this->ruleProductsSelectBuilder = $ruleProductsSelectBuilder ?? ObjectManager::getInstance()->get( + RuleProductsSelectBuilder::class ); - $this->reindexRuleProductPrice = $reindexRuleProductPrice ?: ObjectManager::getInstance()->get( - \Magento\CatalogRule\Model\Indexer\ReindexRuleProductPrice::class + $this->reindexRuleProductPrice = $reindexRuleProductPrice ?? ObjectManager::getInstance()->get( + ReindexRuleProductPrice::class ); - $this->pricesPersistor = $pricesPersistor ?: ObjectManager::getInstance()->get( - \Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor::class + $this->pricesPersistor = $pricesPersistor ?? ObjectManager::getInstance()->get( + RuleProductPricesPersistor::class ); - $this->activeTableSwitcher = $activeTableSwitcher ?: ObjectManager::getInstance()->get( + $this->activeTableSwitcher = $activeTableSwitcher ?? ObjectManager::getInstance()->get( \Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher::class ); + $this->productLoader = $productLoader ?? ObjectManager::getInstance()->get( + ProductLoader::class + ); } /** @@ -251,9 +262,10 @@ protected function doReindexByIds($ids) { $this->cleanByIds($ids); + $products = $this->productLoader->getProducts($ids); foreach ($this->getActiveRules() as $rule) { - foreach ($ids as $productId) { - $this->applyRule($rule, $this->getProduct($productId)); + foreach ($products as $product) { + $this->applyRule($rule, $product); } } } @@ -420,7 +432,7 @@ protected function getTable($tableName) * @param Rule $rule * @return $this * @deprecated 100.2.0 - * @see \Magento\CatalogRule\Model\Indexer\ReindexRuleProduct::execute + * @see ReindexRuleProduct::execute */ protected function updateRuleProductData(Rule $rule) { @@ -446,8 +458,8 @@ protected function updateRuleProductData(Rule $rule) * @throws \Exception * @return $this * @deprecated 100.2.0 - * @see \Magento\CatalogRule\Model\Indexer\ReindexRuleProductPrice::execute - * @see \Magento\CatalogRule\Model\Indexer\ReindexRuleGroupWebsite::execute + * @see ReindexRuleProductPrice::execute + * @see ReindexRuleGroupWebsite::execute */ protected function applyAllRules(Product $product = null) { @@ -461,7 +473,7 @@ protected function applyAllRules(Product $product = null) * * @return $this * @deprecated 100.2.0 - * @see \Magento\CatalogRule\Model\Indexer\ReindexRuleGroupWebsite::execute + * @see ReindexRuleGroupWebsite::execute */ protected function updateCatalogRuleGroupWebsiteData() { @@ -485,7 +497,7 @@ protected function deleteOldData() * @param null $productData * @return float * @deprecated 100.2.0 - * @see \Magento\CatalogRule\Model\Indexer\ProductPriceCalculator::calculate + * @see ProductPriceCalculator::calculate */ protected function calcRuleProductPrice($ruleData, $productData = null) { @@ -498,7 +510,7 @@ protected function calcRuleProductPrice($ruleData, $productData = null) * @return \Zend_Db_Statement_Interface * @throws \Magento\Framework\Exception\LocalizedException * @deprecated 100.2.0 - * @see \Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder::build + * @see RuleProductsSelectBuilder::build */ protected function getRuleProductsStmt($websiteId, Product $product = null) { @@ -510,7 +522,7 @@ protected function getRuleProductsStmt($websiteId, Product $product = null) * @return $this * @throws \Exception * @deprecated 100.2.0 - * @see \Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor::execute + * @see RuleProductPricesPersistor::execute */ protected function saveRuleProductPrices($arrData) { diff --git a/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder/ProductLoader.php b/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder/ProductLoader.php new file mode 100644 index 0000000000000..bce2bea2fd952 --- /dev/null +++ b/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder/ProductLoader.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogRule\Model\Indexer\IndexBuilder; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Catalog\Api\Data\ProductInterface; + +/** + * Product loader that gets products by ids via product repository + */ +class ProductLoader +{ + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + + /** + * @param ProductRepositoryInterface $productRepository + * @param SearchCriteriaBuilder $searchCriteriaBuilder + */ + public function __construct( + ProductRepositoryInterface $productRepository, + SearchCriteriaBuilder $searchCriteriaBuilder + ) { + $this->productRepository = $productRepository; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + } + + /** + * Get products by ids + * + * @param array $productIds + * @return ProductInterface[] + */ + public function getProducts($productIds) + { + $this->searchCriteriaBuilder->addFilter('entity_id', $productIds, 'in'); + $searchCriteria = $this->searchCriteriaBuilder->create(); + $products = $this->productRepository->getList($searchCriteria)->getItems(); + + return $products; + } +} diff --git a/app/code/Magento/CatalogRule/Plugin/Indexer/Category.php b/app/code/Magento/CatalogRule/Plugin/Indexer/Category.php index 8bcc1fd8d6834..0ea0fdda31958 100644 --- a/app/code/Magento/CatalogRule/Plugin/Indexer/Category.php +++ b/app/code/Magento/CatalogRule/Plugin/Indexer/Category.php @@ -36,7 +36,7 @@ public function afterSave( ) { /** @var \Magento\Catalog\Model\Category $result */ $productIds = $result->getAffectedProductIds(); - if ($productIds) { + if ($productIds && !$this->productRuleProcessor->isIndexerScheduled()) { $this->productRuleProcessor->reindexList($productIds); } return $result; diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilder/ProductLoaderTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilder/ProductLoaderTest.php new file mode 100644 index 0000000000000..3509128da79da --- /dev/null +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilder/ProductLoaderTest.php @@ -0,0 +1,96 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogRule\Test\Unit\Model\Indexer\IndexBuilder; + +use Magento\CatalogRule\Model\Indexer\IndexBuilder\ProductLoader; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Catalog\Api\Data\ProductSearchResultsInterface; +use Magento\Catalog\Model\Product; +use Magento\Framework\Api\SearchCriteria; + +class ProductLoaderTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ProductLoader + */ + protected $productLoader; + + /** + * @var ProductRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $productRepository; + + /** + * @var SearchCriteriaBuilder|\PHPUnit_Framework_MockObject_MockObject + */ + private $searchCriteriaBuilder; + + /** + * @var ProductSearchResultsInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $productSearchResultsInterface; + + /** + * @var \Magento\Framework\Api\SearchCriteria|\PHPUnit_Framework_MockObject_MockObject + */ + private $searchCriteria; + + /** + * @var Product|\PHPUnit_Framework_MockObject_MockObject + */ + protected $product; + + /** + * Set up test + * + * @return void + */ + protected function setUp() + { + $this->productRepository = $this->getMockBuilder(ProductRepositoryInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->searchCriteriaBuilder = $this->getMockBuilder(SearchCriteriaBuilder::class) + ->disableOriginalConstructor() + ->getMock(); + $this->productSearchResultsInterface = $this->getMockBuilder(ProductSearchResultsInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->searchCriteria = $this->getMockBuilder(SearchCriteria::class) + ->disableOriginalConstructor() + ->getMock(); + $this->product = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->productLoader = new ProductLoader( + $this->productRepository, + $this->searchCriteriaBuilder + ); + } + + public function testGetProducts() + { + $this->searchCriteriaBuilder->expects($this->once()) + ->method('addFilter') + ->willReturnSelf(); + $this->searchCriteriaBuilder->expects($this->once()) + ->method('create') + ->willReturn($this->searchCriteria); + $this->productRepository->expects($this->once()) + ->method('getList') + ->with($this->searchCriteria) + ->willReturn($this->productSearchResultsInterface); + $iterator = new \ArrayIterator([$this->product]); + $this->productSearchResultsInterface->expects($this->once()) + ->method('getItems') + ->willReturn($iterator); + + $this->assertSame($iterator, $this->productLoader->getProducts([1])); + } +} diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilderTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilderTest.php index 997cf704a8657..8252b512e7810 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilderTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilderTest.php @@ -6,6 +6,9 @@ namespace Magento\CatalogRule\Test\Unit\Model\Indexer; +use Magento\CatalogRule\Model\Indexer\IndexBuilder\ProductLoader; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) @@ -122,10 +125,16 @@ class IndexBuilderTest extends \PHPUnit\Framework\TestCase */ private $reindexRuleGroupWebsite; + /** + * @var ProductLoader|\PHPUnit_Framework_MockObject_MockObject + */ + private $productLoader; + /** * Set up test * * @return void + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ protected function setUp() { @@ -171,36 +180,47 @@ protected function setUp() $this->rules->expects($this->any())->method('getId')->will($this->returnValue(1)); $this->rules->expects($this->any())->method('getWebsiteIds')->will($this->returnValue([1])); $this->rules->expects($this->any())->method('getCustomerGroupIds')->will($this->returnValue([1])); + $this->ruleCollectionFactory->expects($this->any())->method('create')->will($this->returnSelf()); $this->ruleCollectionFactory->expects($this->any())->method('addFieldToFilter')->will( $this->returnValue([$this->rules]) ); + $this->product->expects($this->any())->method('load')->will($this->returnSelf()); $this->product->expects($this->any())->method('getId')->will($this->returnValue(1)); $this->product->expects($this->any())->method('getWebsiteIds')->will($this->returnValue([1])); + $this->rules->expects($this->any())->method('validate')->with($this->product)->willReturn(true); $this->attribute->expects($this->any())->method('getBackend')->will($this->returnValue($this->backend)); $this->productFactory->expects($this->any())->method('create')->will($this->returnValue($this->product)); + $this->productLoader = $this->getMockBuilder(ProductLoader::class) + ->disableOriginalConstructor() + ->getMock(); - $this->indexBuilder = new \Magento\CatalogRule\Model\Indexer\IndexBuilder( - $this->ruleCollectionFactory, - $this->priceCurrency, - $this->resource, - $this->storeManager, - $this->logger, - $this->eavConfig, - $this->dateFormat, - $this->dateTime, - $this->productFactory + $this->indexBuilder = (new ObjectManager($this))->getObject( + \Magento\CatalogRule\Model\Indexer\IndexBuilder::class, + [ + 'ruleCollectionFactory' => $this->ruleCollectionFactory, + 'priceCurrency' => $this->priceCurrency, + 'resource' => $this->resource, + 'storeManager' => $this->storeManager, + 'logger' => $this->logger, + 'eavConfig' => $this->eavConfig, + 'dateFormat' => $this->dateFormat, + 'dateTime' => $this->dateTime, + 'productFactory' => $this->productFactory, + 'productLoader' => $this->productLoader, + ] ); + $this->reindexRuleProductPrice = $this->getMockBuilder(\Magento\CatalogRule\Model\Indexer\ReindexRuleProductPrice::class) - ->disableOriginalConstructor() - ->getMock(); + ->disableOriginalConstructor() + ->getMock(); $this->reindexRuleGroupWebsite = $this->getMockBuilder(\Magento\CatalogRule\Model\Indexer\ReindexRuleGroupWebsite::class) - ->disableOriginalConstructor() - ->getMock(); + ->disableOriginalConstructor() + ->getMock(); $this->setProperties($this->indexBuilder, [ 'metadataPool' => $this->metadataPool, 'reindexRuleProductPrice' => $this->reindexRuleProductPrice, @@ -235,6 +255,11 @@ public function testUpdateCatalogRuleGroupWebsiteData() ->method('getBackend') ->will($this->returnValue($backendModelMock)); + $iterator = new \ArrayIterator([$this->product]); + $this->productLoader->expects($this->once()) + ->method('getProducts') + ->willReturn($iterator); + $this->reindexRuleProductPrice->expects($this->once())->method('execute')->willReturn(true); $this->reindexRuleGroupWebsite->expects($this->once())->method('execute')->willReturn(true); diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php index 92a46facbe71c..539e5c3f42f15 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php @@ -85,7 +85,7 @@ public function execute(\Magento\Framework\Event\Observer $observer) $mapsGenerated = false; if ($category->dataHasChangedFor('url_key') || $category->dataHasChangedFor('is_anchor') - || $category->getIsChangedProductList() + || $category->getChangedProductIds() ) { if ($category->dataHasChangedFor('url_key')) { $categoryUrlRewriteResult = $this->categoryUrlRewriteGenerator->generate($category); diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/UrlRewriteHandler.php b/app/code/Magento/CatalogUrlRewrite/Observer/UrlRewriteHandler.php index 5a6777f94e2d5..9892465d1538a 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/UrlRewriteHandler.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/UrlRewriteHandler.php @@ -104,7 +104,8 @@ public function generateProductUrlRewrites(\Magento\Catalog\Model\Category $cate $this->isSkippedProduct[$category->getEntityId()] = []; $saveRewriteHistory = $category->getData('save_rewrites_history'); $storeId = $category->getStoreId(); - if ($category->getAffectedProductIds()) { + + if ($category->getChangedProductIds()) { $this->isSkippedProduct[$category->getEntityId()] = $category->getAffectedProductIds(); /* @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */ $collection = $this->productCollectionFactory->create() @@ -140,6 +141,7 @@ public function generateProductUrlRewrites(\Magento\Catalog\Model\Category $cate ) ); } + foreach ($this->childrenCategoriesProvider->getChildren($category, true) as $childCategory) { $mergeDataProvider->merge( $this->getCategoryProductsUrlRewrites( diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/UrlRewriteHandlerTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/UrlRewriteHandlerTest.php index 747e0cfa771fd..b18597a42bf94 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/UrlRewriteHandlerTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/UrlRewriteHandlerTest.php @@ -127,7 +127,7 @@ public function testGenerateProductUrlRewrites() { /* @var \Magento\Catalog\Model\Category|\PHPUnit_Framework_MockObject_MockObject $category */ $category = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) - ->setMethods(['getEntityId', 'getStoreId', 'getData', 'getAffectedProductIds']) + ->setMethods(['getEntityId', 'getStoreId', 'getData', 'getChangedProductIds']) ->disableOriginalConstructor() ->getMock(); $category->expects($this->any()) From 524f4b8e517eb9d26f0e3591f5991819c12bdfa0 Mon Sep 17 00:00:00 2001 From: Patrick McLain <pmclain@somethingdigital.com> Date: Wed, 28 Feb 2018 21:06:54 -0500 Subject: [PATCH 032/668] Move libraries back to require-dev --- composer.json | 4 +- composer.lock | 1516 ++++++++++++++++++++++++------------------------- 2 files changed, 760 insertions(+), 760 deletions(-) diff --git a/composer.json b/composer.json index a863fedd5cb1a..c47ec1bcfafc5 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,6 @@ "colinmollenhour/credis": "1.6", "colinmollenhour/php-redis-session-abstract": "~1.3.8", "composer/composer": "~1.6.0", - "friendsofphp/php-cs-fixer": "~2.10.0", "magento/composer": "1.3.0.x-dev", "magento/magento-composer-installer": ">=0.1.11", "magento/zendframework1": "~1.13.0", @@ -44,7 +43,6 @@ "pelago/emogrifier": "^2.0.0", "phpseclib/phpseclib": "2.0.*", "ramsey/uuid": "3.6.1", - "sebastian/phpcpd": "~3.0.0", "symfony/console": "~4.0.0", "symfony/event-dispatcher": "~4.0.0", "symfony/process": "~4.0.0", @@ -79,10 +77,12 @@ "zendframework/zend-view": "^2.8.1" }, "require-dev": { + "friendsofphp/php-cs-fixer": "~2.10.0", "lusitanian/oauth": "~0.8.10", "pdepend/pdepend": "2.5.0", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.2.0", + "sebastian/phpcpd": "~3.0.0", "squizlabs/php_codesniffer": "3.0.1" }, "replace": { diff --git a/composer.lock b/composer.lock index 5e38e141bcd3c..107355726f8c4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "e0d712daffa20660e5b1c4cbfc459304", + "content-hash": "7c1530aa839699b0654824ae76456ba9", "packages": [ { "name": "braintree/braintree_php", @@ -488,215 +488,6 @@ "homepage": "https://github.com/container-interop/container-interop", "time": "2017-02-14T19:40:03+00:00" }, - { - "name": "doctrine/annotations", - "version": "v1.6.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", - "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", - "shasum": "" - }, - "require": { - "doctrine/lexer": "1.*", - "php": "^7.1" - }, - "require-dev": { - "doctrine/cache": "1.*", - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Docblock Annotations Parser", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "time": "2017-12-06T07:11:42+00:00" - }, - { - "name": "doctrine/lexer", - "version": "v1.0.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Lexer\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "lexer", - "parser" - ], - "time": "2014-09-09T13:34:57+00:00" - }, - { - "name": "friendsofphp/php-cs-fixer", - "version": "v2.10.3", - "source": { - "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "1634a2c250bf4640f1c5c963f63b413c2d966c8a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/1634a2c250bf4640f1c5c963f63b413c2d966c8a", - "reference": "1634a2c250bf4640f1c5c963f63b413c2d966c8a", - "shasum": "" - }, - "require": { - "composer/semver": "^1.4", - "doctrine/annotations": "^1.2", - "ext-json": "*", - "ext-tokenizer": "*", - "php": "^5.6 || >=7.0 <7.3", - "php-cs-fixer/diff": "^1.2", - "symfony/console": "^3.2 || ^4.0", - "symfony/event-dispatcher": "^3.0 || ^4.0", - "symfony/filesystem": "^3.0 || ^4.0", - "symfony/finder": "^3.0 || ^4.0", - "symfony/options-resolver": "^3.0 || ^4.0", - "symfony/polyfill-php70": "^1.0", - "symfony/polyfill-php72": "^1.4", - "symfony/process": "^3.0 || ^4.0", - "symfony/stopwatch": "^3.0 || ^4.0" - }, - "conflict": { - "hhvm": "*" - }, - "require-dev": { - "johnkary/phpunit-speedtrap": "^1.1 || ^2.0@dev", - "justinrainbow/json-schema": "^5.0", - "keradus/cli-executor": "^1.0", - "mikey179/vfsstream": "^1.6", - "php-coveralls/php-coveralls": "^2.0", - "php-cs-fixer/accessible-object": "^1.0", - "phpunit/phpunit": "^5.7.23 || ^6.4.3", - "phpunitgoodpractices/traits": "^1.0", - "symfony/phpunit-bridge": "^3.2.2 || ^4.0" - }, - "suggest": { - "ext-mbstring": "For handling non-UTF8 characters in cache signature.", - "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." - }, - "bin": [ - "php-cs-fixer" - ], - "type": "application", - "autoload": { - "psr-4": { - "PhpCsFixer\\": "src/" - }, - "classmap": [ - "tests/Test/AbstractFixerTestCase.php", - "tests/Test/AbstractIntegrationCaseFactory.php", - "tests/Test/AbstractIntegrationTestCase.php", - "tests/Test/Assert/AssertTokensTrait.php", - "tests/Test/Constraint/SameStringsConstraint.php", - "tests/Test/IntegrationCase.php", - "tests/Test/IntegrationCaseFactory.php", - "tests/Test/IntegrationCaseFactoryInterface.php", - "tests/Test/InternalIntegrationCaseFactory.php", - "tests/TestCase.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "A tool to automatically fix PHP code style", - "time": "2018-02-22T16:49:33+00:00" - }, { "name": "justinrainbow/json-schema", "version": "5.2.6", @@ -1183,108 +974,57 @@ "time": "2018-01-05T23:30:21+00:00" }, { - "name": "php-cs-fixer/diff", - "version": "v1.3.0", + "name": "phpseclib/phpseclib", + "version": "2.0.9", "source": { "type": "git", - "url": "https://github.com/PHP-CS-Fixer/diff.git", - "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756" + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "c9a3fe35e20eb6eeaca716d6a23cde03f52d1558" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/78bb099e9c16361126c86ce82ec4405ebab8e756", - "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/c9a3fe35e20eb6eeaca716d6a23cde03f52d1558", + "reference": "c9a3fe35e20eb6eeaca716d6a23cde03f52d1558", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "^5.7.23 || ^6.4.3", - "symfony/process": "^3.3" + "phing/phing": "~2.7", + "phpunit/phpunit": "~4.0", + "sami/sami": "~2.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "suggest": { + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." }, "type": "library", "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib\\": "phpseclib/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "SpacePossum" - } - ], - "description": "sebastian/diff v2 backport support for PHP5.6", - "homepage": "https://github.com/PHP-CS-Fixer", - "keywords": [ - "diff" - ], - "time": "2018-02-15T16:58:55+00:00" - }, - { - "name": "phpseclib/phpseclib", - "version": "2.0.9", - "source": { - "type": "git", - "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "c9a3fe35e20eb6eeaca716d6a23cde03f52d1558" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/c9a3fe35e20eb6eeaca716d6a23cde03f52d1558", - "reference": "c9a3fe35e20eb6eeaca716d6a23cde03f52d1558", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phing/phing": "~2.7", - "phpunit/phpunit": "~4.0", - "sami/sami": "~2.0", - "squizlabs/php_codesniffer": "~2.0" - }, - "suggest": { - "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", - "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", - "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", - "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." - }, - "type": "library", - "autoload": { - "files": [ - "phpseclib/bootstrap.php" - ], - "psr-4": { - "phpseclib\\": "phpseclib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" - }, - { - "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" }, { "name": "Andreas Fischer", @@ -1325,55 +1065,6 @@ ], "time": "2017-11-29T06:38:08+00:00" }, - { - "name": "phpunit/php-timer", - "version": "1.0.9", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2017-02-26T11:10:40+00:00" - }, { "name": "psr/container", "version": "1.0.0", @@ -1552,138 +1243,6 @@ ], "time": "2017-03-26T20:37:53+00:00" }, - { - "name": "sebastian/finder-facade", - "version": "1.2.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/finder-facade.git", - "reference": "4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f", - "reference": "4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f", - "shasum": "" - }, - "require": { - "symfony/finder": "~2.3|~3.0|~4.0", - "theseer/fdomdocument": "~1.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", - "homepage": "https://github.com/sebastianbergmann/finder-facade", - "time": "2017-11-18T17:31:49+00:00" - }, - { - "name": "sebastian/phpcpd", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpcpd.git", - "reference": "dfed51c1288790fc957c9433e2f49ab152e8a564" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/dfed51c1288790fc957c9433e2f49ab152e8a564", - "reference": "dfed51c1288790fc957c9433e2f49ab152e8a564", - "shasum": "" - }, - "require": { - "php": "^5.6|^7.0", - "phpunit/php-timer": "^1.0.6", - "sebastian/finder-facade": "^1.1", - "sebastian/version": "^1.0|^2.0", - "symfony/console": "^2.7|^3.0|^4.0" - }, - "bin": [ - "phpcpd" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Copy/Paste Detector (CPD) for PHP code.", - "homepage": "https://github.com/sebastianbergmann/phpcpd", - "time": "2017-11-16T08:49:28+00:00" - }, - { - "name": "sebastian/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" - }, { "name": "seld/cli-prompt", "version": "1.0.3", @@ -2055,66 +1614,12 @@ "time": "2018-01-03T07:37:34+00:00" }, { - "name": "symfony/options-resolver", - "version": "v4.0.4", + "name": "symfony/polyfill-mbstring", + "version": "v1.7.0", "source": { "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "371532a2cfe932f7a3766dd4c45364566def1dd0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/371532a2cfe932f7a3766dd4c45364566def1dd0", - "reference": "371532a2cfe932f7a3766dd4c45364566def1dd0", - "shasum": "" - }, - "require": { - "php": "^7.1.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\OptionsResolver\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony OptionsResolver Component", - "homepage": "https://symfony.com", - "keywords": [ - "config", - "configuration", - "options" - ], - "time": "2018-01-18T22:19:33+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b" + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b" }, "dist": { "type": "zip", @@ -2167,120 +1672,6 @@ ], "time": "2018-01-30T19:27:44+00:00" }, - { - "name": "symfony/polyfill-php70", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3532bfcd8f933a7816f3a0a59682fc404776600f", - "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f", - "shasum": "" - }, - "require": { - "paragonie/random_compat": "~1.0|~2.0", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php70\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-30T19:27:44+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "8eca20c8a369e069d4f4c2ac9895144112867422" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/8eca20c8a369e069d4f4c2ac9895144112867422", - "reference": "8eca20c8a369e069d4f4c2ac9895144112867422", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-31T17:43:24+00:00" - }, { "name": "symfony/process", "version": "v4.0.4", @@ -2330,55 +1721,6 @@ "homepage": "https://symfony.com", "time": "2018-01-29T09:06:29+00:00" }, - { - "name": "symfony/stopwatch", - "version": "v4.0.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "d52321f0e2b596bd03b5d1dd6eebe71caa925704" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/d52321f0e2b596bd03b5d1dd6eebe71caa925704", - "reference": "d52321f0e2b596bd03b5d1dd6eebe71caa925704", - "shasum": "" - }, - "require": { - "php": "^7.1.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Stopwatch Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:38:00+00:00" - }, { "name": "tedivm/jshrink", "version": "v1.1.0", @@ -2425,46 +1767,6 @@ ], "time": "2015-07-04T07:35:09+00:00" }, - { - "name": "theseer/fdomdocument", - "version": "1.6.6", - "source": { - "type": "git", - "url": "https://github.com/theseer/fDOMDocument.git", - "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/6e8203e40a32a9c770bcb62fe37e68b948da6dca", - "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "lib-libxml": "*", - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "lead" - } - ], - "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", - "homepage": "https://github.com/theseer/fDOMDocument", - "time": "2017-06-30T11:53:12+00:00" - }, { "name": "tubalmartin/cssmin", "version": "v4.1.0", @@ -4472,8 +3774,76 @@ ], "packages-dev": [ { - "name": "doctrine/instantiator", - "version": "1.0.5", + "name": "doctrine/annotations", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", + "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": "^7.1" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2017-12-06T07:11:42+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", @@ -4525,6 +3895,147 @@ ], "time": "2015-06-14T21:17:01+00:00" }, + { + "name": "doctrine/lexer", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09T13:34:57+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v2.10.3", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", + "reference": "1634a2c250bf4640f1c5c963f63b413c2d966c8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/1634a2c250bf4640f1c5c963f63b413c2d966c8a", + "reference": "1634a2c250bf4640f1c5c963f63b413c2d966c8a", + "shasum": "" + }, + "require": { + "composer/semver": "^1.4", + "doctrine/annotations": "^1.2", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^5.6 || >=7.0 <7.3", + "php-cs-fixer/diff": "^1.2", + "symfony/console": "^3.2 || ^4.0", + "symfony/event-dispatcher": "^3.0 || ^4.0", + "symfony/filesystem": "^3.0 || ^4.0", + "symfony/finder": "^3.0 || ^4.0", + "symfony/options-resolver": "^3.0 || ^4.0", + "symfony/polyfill-php70": "^1.0", + "symfony/polyfill-php72": "^1.4", + "symfony/process": "^3.0 || ^4.0", + "symfony/stopwatch": "^3.0 || ^4.0" + }, + "conflict": { + "hhvm": "*" + }, + "require-dev": { + "johnkary/phpunit-speedtrap": "^1.1 || ^2.0@dev", + "justinrainbow/json-schema": "^5.0", + "keradus/cli-executor": "^1.0", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.0", + "php-cs-fixer/accessible-object": "^1.0", + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "phpunitgoodpractices/traits": "^1.0", + "symfony/phpunit-bridge": "^3.2.2 || ^4.0" + }, + "suggest": { + "ext-mbstring": "For handling non-UTF8 characters in cache signature.", + "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "classmap": [ + "tests/Test/AbstractFixerTestCase.php", + "tests/Test/AbstractIntegrationCaseFactory.php", + "tests/Test/AbstractIntegrationTestCase.php", + "tests/Test/Assert/AssertTokensTrait.php", + "tests/Test/Constraint/SameStringsConstraint.php", + "tests/Test/IntegrationCase.php", + "tests/Test/IntegrationCaseFactory.php", + "tests/Test/IntegrationCaseFactoryInterface.php", + "tests/Test/InternalIntegrationCaseFactory.php", + "tests/TestCase.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "time": "2018-02-22T16:49:33+00:00" + }, { "name": "lusitanian/oauth", "version": "v0.8.10", @@ -4780,50 +4291,101 @@ "time": "2017-03-05T17:38:23+00:00" }, { - "name": "phpdocumentor/reflection-common", - "version": "1.0.1", + "name": "php-cs-fixer/diff", + "version": "v1.3.0", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + "url": "https://github.com/PHP-CS-Fixer/diff.git", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/78bb099e9c16361126c86ce82ec4405ebab8e756", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756", "shasum": "" }, "require": { - "php": ">=5.5" + "php": "^5.6 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^4.6" + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "symfony/process": "^3.3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "SpacePossum" } ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", + "description": "sebastian/diff v2 backport support for PHP5.6", + "homepage": "https://github.com/PHP-CS-Fixer", + "keywords": [ + "diff" + ], + "time": "2018-02-15T16:58:55+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", "keywords": [ "FQSEN", "phpDocumentor", @@ -5211,6 +4773,55 @@ ], "time": "2015-06-21T13:50:34+00:00" }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26T11:10:40+00:00" + }, { "name": "phpunit/php-token-stream", "version": "2.0.2", @@ -5681,6 +5292,45 @@ ], "time": "2017-04-03T13:19:02+00:00" }, + { + "name": "sebastian/finder-facade", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/finder-facade.git", + "reference": "4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f", + "reference": "4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f", + "shasum": "" + }, + "require": { + "symfony/finder": "~2.3|~3.0|~4.0", + "theseer/fdomdocument": "~1.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", + "homepage": "https://github.com/sebastianbergmann/finder-facade", + "time": "2017-11-18T17:31:49+00:00" + }, { "name": "sebastian/global-state", "version": "2.0.0", @@ -5824,6 +5474,56 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "time": "2017-03-29T09:07:27+00:00" }, + { + "name": "sebastian/phpcpd", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpcpd.git", + "reference": "dfed51c1288790fc957c9433e2f49ab152e8a564" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/dfed51c1288790fc957c9433e2f49ab152e8a564", + "reference": "dfed51c1288790fc957c9433e2f49ab152e8a564", + "shasum": "" + }, + "require": { + "php": "^5.6|^7.0", + "phpunit/php-timer": "^1.0.6", + "sebastian/finder-facade": "^1.1", + "sebastian/version": "^1.0|^2.0", + "symfony/console": "^2.7|^3.0|^4.0" + }, + "bin": [ + "phpcpd" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Copy/Paste Detector (CPD) for PHP code.", + "homepage": "https://github.com/sebastianbergmann/phpcpd", + "time": "2017-11-16T08:49:28+00:00" + }, { "name": "sebastian/recursion-context", "version": "3.0.0", @@ -5919,6 +5619,49 @@ "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "time": "2015-07-28T20:34:47+00:00" }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, { "name": "squizlabs/php_codesniffer", "version": "3.0.1", @@ -6160,6 +5903,263 @@ "homepage": "https://symfony.com", "time": "2018-01-29T09:16:57+00:00" }, + { + "name": "symfony/options-resolver", + "version": "v4.0.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "371532a2cfe932f7a3766dd4c45364566def1dd0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/371532a2cfe932f7a3766dd4c45364566def1dd0", + "reference": "371532a2cfe932f7a3766dd4c45364566def1dd0", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony OptionsResolver Component", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "time": "2018-01-18T22:19:33+00:00" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3532bfcd8f933a7816f3a0a59682fc404776600f", + "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-01-30T19:27:44+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "8eca20c8a369e069d4f4c2ac9895144112867422" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/8eca20c8a369e069d4f4c2ac9895144112867422", + "reference": "8eca20c8a369e069d4f4c2ac9895144112867422", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-01-31T17:43:24+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v4.0.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "d52321f0e2b596bd03b5d1dd6eebe71caa925704" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/d52321f0e2b596bd03b5d1dd6eebe71caa925704", + "reference": "d52321f0e2b596bd03b5d1dd6eebe71caa925704", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "https://symfony.com", + "time": "2018-01-03T07:38:00+00:00" + }, + { + "name": "theseer/fdomdocument", + "version": "1.6.6", + "source": { + "type": "git", + "url": "https://github.com/theseer/fDOMDocument.git", + "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/6e8203e40a32a9c770bcb62fe37e68b948da6dca", + "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "lib-libxml": "*", + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "lead" + } + ], + "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", + "homepage": "https://github.com/theseer/fDOMDocument", + "time": "2017-06-30T11:53:12+00:00" + }, { "name": "theseer/tokenizer", "version": "1.1.0", From e20d5b8f024eba4010d6d561a31100838316cccf Mon Sep 17 00:00:00 2001 From: Patrick McLain <pmclain@somethingdigital.com> Date: Wed, 28 Feb 2018 21:19:05 -0500 Subject: [PATCH 033/668] Update PHP version requirements in all composer.json Update to "~7.1.3||~7.2.0" --- app/code/Magento/AdminNotification/composer.json | 2 +- app/code/Magento/AdvancedPricingImportExport/composer.json | 2 +- app/code/Magento/Analytics/composer.json | 2 +- app/code/Magento/Authorization/composer.json | 2 +- app/code/Magento/Authorizenet/composer.json | 2 +- app/code/Magento/Backend/composer.json | 2 +- app/code/Magento/Backup/composer.json | 2 +- app/code/Magento/Braintree/composer.json | 2 +- app/code/Magento/Bundle/composer.json | 2 +- app/code/Magento/BundleGraphQl/composer.json | 2 +- app/code/Magento/BundleImportExport/composer.json | 2 +- app/code/Magento/CacheInvalidate/composer.json | 2 +- app/code/Magento/Captcha/composer.json | 2 +- app/code/Magento/Catalog/composer.json | 2 +- app/code/Magento/CatalogAnalytics/composer.json | 2 +- app/code/Magento/CatalogGraphQl/composer.json | 2 +- app/code/Magento/CatalogImportExport/composer.json | 2 +- app/code/Magento/CatalogInventory/composer.json | 2 +- app/code/Magento/CatalogRule/composer.json | 2 +- app/code/Magento/CatalogRuleConfigurable/composer.json | 2 +- app/code/Magento/CatalogSearch/composer.json | 2 +- app/code/Magento/CatalogUrlRewrite/composer.json | 2 +- app/code/Magento/CatalogUrlRewriteGraphQl/composer.json | 2 +- app/code/Magento/CatalogWidget/composer.json | 2 +- app/code/Magento/Checkout/composer.json | 2 +- app/code/Magento/CheckoutAgreements/composer.json | 2 +- app/code/Magento/Cms/composer.json | 2 +- app/code/Magento/CmsUrlRewrite/composer.json | 2 +- app/code/Magento/CmsUrlRewriteGraphQl/composer.json | 2 +- app/code/Magento/Config/composer.json | 2 +- app/code/Magento/ConfigurableImportExport/composer.json | 2 +- app/code/Magento/ConfigurableProduct/composer.json | 2 +- app/code/Magento/ConfigurableProductGraphQl/composer.json | 2 +- app/code/Magento/ConfigurableProductSales/composer.json | 2 +- app/code/Magento/Contact/composer.json | 2 +- app/code/Magento/Cookie/composer.json | 2 +- app/code/Magento/Cron/composer.json | 2 +- app/code/Magento/CurrencySymbol/composer.json | 2 +- app/code/Magento/Customer/composer.json | 2 +- app/code/Magento/CustomerAnalytics/composer.json | 2 +- app/code/Magento/CustomerGraphQl/composer.json | 2 +- app/code/Magento/CustomerImportExport/composer.json | 2 +- app/code/Magento/Deploy/composer.json | 2 +- app/code/Magento/Developer/composer.json | 2 +- app/code/Magento/Dhl/composer.json | 2 +- app/code/Magento/Directory/composer.json | 2 +- app/code/Magento/Downloadable/composer.json | 2 +- app/code/Magento/DownloadableGraphQl/composer.json | 2 +- app/code/Magento/DownloadableImportExport/composer.json | 2 +- app/code/Magento/Eav/composer.json | 2 +- app/code/Magento/EavGraphQl/composer.json | 2 +- app/code/Magento/Email/composer.json | 2 +- app/code/Magento/EncryptionKey/composer.json | 2 +- app/code/Magento/Fedex/composer.json | 2 +- app/code/Magento/GiftMessage/composer.json | 2 +- app/code/Magento/GoogleAdwords/composer.json | 2 +- app/code/Magento/GoogleAnalytics/composer.json | 2 +- app/code/Magento/GoogleOptimizer/composer.json | 2 +- app/code/Magento/GraphQl/composer.json | 2 +- app/code/Magento/GroupedImportExport/composer.json | 2 +- app/code/Magento/GroupedProduct/composer.json | 2 +- app/code/Magento/GroupedProductGraphQl/composer.json | 2 +- app/code/Magento/ImportExport/composer.json | 2 +- app/code/Magento/Indexer/composer.json | 2 +- app/code/Magento/InstantPurchase/composer.json | 2 +- app/code/Magento/Integration/composer.json | 2 +- app/code/Magento/LayeredNavigation/composer.json | 2 +- app/code/Magento/Marketplace/composer.json | 2 +- app/code/Magento/MediaStorage/composer.json | 2 +- app/code/Magento/Msrp/composer.json | 2 +- app/code/Magento/Multishipping/composer.json | 2 +- app/code/Magento/NewRelicReporting/composer.json | 2 +- app/code/Magento/Newsletter/composer.json | 2 +- app/code/Magento/OfflinePayments/composer.json | 2 +- app/code/Magento/OfflineShipping/composer.json | 2 +- app/code/Magento/PageCache/composer.json | 2 +- app/code/Magento/Payment/composer.json | 2 +- app/code/Magento/Paypal/composer.json | 2 +- app/code/Magento/Persistent/composer.json | 2 +- app/code/Magento/ProductAlert/composer.json | 2 +- app/code/Magento/ProductVideo/composer.json | 2 +- app/code/Magento/Quote/composer.json | 2 +- app/code/Magento/QuoteAnalytics/composer.json | 2 +- app/code/Magento/ReleaseNotification/composer.json | 2 +- app/code/Magento/Reports/composer.json | 2 +- app/code/Magento/RequireJs/composer.json | 2 +- app/code/Magento/Review/composer.json | 2 +- app/code/Magento/ReviewAnalytics/composer.json | 2 +- app/code/Magento/Robots/composer.json | 2 +- app/code/Magento/Rss/composer.json | 2 +- app/code/Magento/Rule/composer.json | 2 +- app/code/Magento/Sales/composer.json | 2 +- app/code/Magento/SalesAnalytics/composer.json | 2 +- app/code/Magento/SalesInventory/composer.json | 2 +- app/code/Magento/SalesRule/composer.json | 2 +- app/code/Magento/SalesSequence/composer.json | 2 +- app/code/Magento/SampleData/composer.json | 2 +- app/code/Magento/Search/composer.json | 2 +- app/code/Magento/Security/composer.json | 2 +- app/code/Magento/SendFriend/composer.json | 2 +- app/code/Magento/Shipping/composer.json | 2 +- app/code/Magento/Signifyd/composer.json | 2 +- app/code/Magento/Sitemap/composer.json | 2 +- app/code/Magento/Store/composer.json | 2 +- app/code/Magento/Swagger/composer.json | 2 +- app/code/Magento/Swatches/composer.json | 2 +- app/code/Magento/SwatchesGraphQl/composer.json | 2 +- app/code/Magento/SwatchesLayeredNavigation/composer.json | 2 +- app/code/Magento/Tax/composer.json | 2 +- app/code/Magento/TaxGraphQl/composer.json | 2 +- app/code/Magento/TaxImportExport/composer.json | 2 +- app/code/Magento/Theme/composer.json | 2 +- app/code/Magento/Tinymce3/composer.json | 2 +- app/code/Magento/Translation/composer.json | 2 +- app/code/Magento/Ui/composer.json | 2 +- app/code/Magento/Ups/composer.json | 2 +- app/code/Magento/UrlRewrite/composer.json | 2 +- app/code/Magento/UrlRewriteGraphQl/composer.json | 2 +- app/code/Magento/User/composer.json | 2 +- app/code/Magento/Usps/composer.json | 2 +- app/code/Magento/Variable/composer.json | 2 +- app/code/Magento/Vault/composer.json | 2 +- app/code/Magento/Version/composer.json | 2 +- app/code/Magento/Webapi/composer.json | 2 +- app/code/Magento/WebapiSecurity/composer.json | 2 +- app/code/Magento/Weee/composer.json | 2 +- app/code/Magento/WeeeGraphQl/composer.json | 2 +- app/code/Magento/Widget/composer.json | 2 +- app/code/Magento/Wishlist/composer.json | 2 +- app/code/Magento/WishlistAnalytics/composer.json | 2 +- .../Magento/FunctionalTest/AdminNotification/composer.json | 2 +- .../FunctionalTest/AdvancedPricingImportExport/composer.json | 2 +- .../functional/Magento/FunctionalTest/Analytics/composer.json | 2 +- .../Magento/FunctionalTest/Authorization/composer.json | 2 +- .../Magento/FunctionalTest/Authorizenet/composer.json | 2 +- .../functional/Magento/FunctionalTest/Backend/composer.json | 2 +- .../functional/Magento/FunctionalTest/Backup/composer.json | 2 +- .../functional/Magento/FunctionalTest/Braintree/composer.json | 2 +- .../functional/Magento/FunctionalTest/Bundle/composer.json | 2 +- .../Magento/FunctionalTest/BundleImportExport/composer.json | 2 +- .../Magento/FunctionalTest/CacheInvalidate/composer.json | 2 +- .../functional/Magento/FunctionalTest/Captcha/composer.json | 2 +- .../functional/Magento/FunctionalTest/Catalog/composer.json | 2 +- .../Magento/FunctionalTest/CatalogAnalytics/composer.json | 2 +- .../Magento/FunctionalTest/CatalogImportExport/composer.json | 2 +- .../Magento/FunctionalTest/CatalogInventory/composer.json | 2 +- .../functional/Magento/FunctionalTest/CatalogRule/composer.json | 2 +- .../FunctionalTest/CatalogRuleConfigurable/composer.json | 2 +- .../Magento/FunctionalTest/CatalogSearch/composer.json | 2 +- .../Magento/FunctionalTest/CatalogUrlRewrite/composer.json | 2 +- .../Magento/FunctionalTest/CatalogWidget/composer.json | 2 +- .../functional/Magento/FunctionalTest/Checkout/composer.json | 2 +- .../Magento/FunctionalTest/CheckoutAgreements/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Cms/composer.json | 2 +- .../Magento/FunctionalTest/CmsUrlRewrite/composer.json | 2 +- .../functional/Magento/FunctionalTest/Config/composer.json | 2 +- .../FunctionalTest/ConfigurableImportExport/composer.json | 2 +- .../Magento/FunctionalTest/ConfigurableProduct/composer.json | 2 +- .../FunctionalTest/ConfigurableProductSales/composer.json | 2 +- .../functional/Magento/FunctionalTest/Contact/composer.json | 2 +- .../functional/Magento/FunctionalTest/Cookie/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Cron/composer.json | 2 +- .../Magento/FunctionalTest/CurrencySymbol/composer.json | 2 +- .../functional/Magento/FunctionalTest/Customer/composer.json | 2 +- .../Magento/FunctionalTest/CustomerAnalytics/composer.json | 2 +- .../Magento/FunctionalTest/CustomerImportExport/composer.json | 2 +- .../functional/Magento/FunctionalTest/Deploy/composer.json | 2 +- .../functional/Magento/FunctionalTest/Developer/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Dhl/composer.json | 2 +- .../functional/Magento/FunctionalTest/Directory/composer.json | 2 +- .../Magento/FunctionalTest/Downloadable/composer.json | 2 +- .../FunctionalTest/DownloadableImportExport/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Eav/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Email/composer.json | 2 +- .../Magento/FunctionalTest/EncryptionKey/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Fedex/composer.json | 2 +- .../functional/Magento/FunctionalTest/GiftMessage/composer.json | 2 +- .../Magento/FunctionalTest/GoogleAdwords/composer.json | 2 +- .../Magento/FunctionalTest/GoogleAnalytics/composer.json | 2 +- .../Magento/FunctionalTest/GoogleOptimizer/composer.json | 2 +- .../functional/Magento/FunctionalTest/GraphQl/composer.json | 2 +- .../Magento/FunctionalTest/GroupedImportExport/composer.json | 2 +- .../Magento/FunctionalTest/GroupedProduct/composer.json | 2 +- .../Magento/FunctionalTest/ImportExport/composer.json | 2 +- .../functional/Magento/FunctionalTest/Indexer/composer.json | 2 +- .../Magento/FunctionalTest/InstantPurchase/composer.json | 2 +- .../functional/Magento/FunctionalTest/Integration/composer.json | 2 +- .../Magento/FunctionalTest/LayeredNavigation/composer.json | 2 +- .../functional/Magento/FunctionalTest/Marketplace/composer.json | 2 +- .../Magento/FunctionalTest/MediaStorage/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Msrp/composer.json | 2 +- .../Magento/FunctionalTest/Multishipping/composer.json | 2 +- .../Magento/FunctionalTest/NewRelicReporting/composer.json | 2 +- .../functional/Magento/FunctionalTest/Newsletter/composer.json | 2 +- .../Magento/FunctionalTest/OfflinePayments/composer.json | 2 +- .../Magento/FunctionalTest/OfflineShipping/composer.json | 2 +- .../functional/Magento/FunctionalTest/PageCache/composer.json | 2 +- .../functional/Magento/FunctionalTest/Payment/composer.json | 2 +- .../functional/Magento/FunctionalTest/Paypal/composer.json | 2 +- .../functional/Magento/FunctionalTest/Persistent/composer.json | 2 +- .../Magento/FunctionalTest/ProductAlert/composer.json | 2 +- .../Magento/FunctionalTest/ProductVideo/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Quote/composer.json | 2 +- .../Magento/FunctionalTest/QuoteAnalytics/composer.json | 2 +- .../functional/Magento/FunctionalTest/Reports/composer.json | 2 +- .../functional/Magento/FunctionalTest/RequireJs/composer.json | 2 +- .../functional/Magento/FunctionalTest/Review/composer.json | 2 +- .../Magento/FunctionalTest/ReviewAnalytics/composer.json | 2 +- .../functional/Magento/FunctionalTest/Robots/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Rss/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Rule/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Sales/composer.json | 2 +- .../Magento/FunctionalTest/SalesAnalytics/composer.json | 2 +- .../Magento/FunctionalTest/SalesInventory/composer.json | 2 +- .../functional/Magento/FunctionalTest/SalesRule/composer.json | 2 +- .../Magento/FunctionalTest/SalesSequence/composer.json | 2 +- .../functional/Magento/FunctionalTest/SampleData/composer.json | 2 +- .../Magento/FunctionalTest/SampleTemplates/composer.json | 2 +- .../functional/Magento/FunctionalTest/SampleTests/composer.json | 2 +- .../functional/Magento/FunctionalTest/Search/composer.json | 2 +- .../functional/Magento/FunctionalTest/Security/composer.json | 2 +- .../functional/Magento/FunctionalTest/SendFriend/composer.json | 2 +- .../functional/Magento/FunctionalTest/Shipping/composer.json | 2 +- .../functional/Magento/FunctionalTest/Sitemap/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Store/composer.json | 2 +- .../functional/Magento/FunctionalTest/Swagger/composer.json | 2 +- .../functional/Magento/FunctionalTest/Swatches/composer.json | 2 +- .../FunctionalTest/SwatchesLayeredNavigation/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Tax/composer.json | 2 +- .../Magento/FunctionalTest/TaxImportExport/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Theme/composer.json | 2 +- .../functional/Magento/FunctionalTest/Translation/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Ui/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Ups/composer.json | 2 +- .../functional/Magento/FunctionalTest/UrlRewrite/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/User/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Usps/composer.json | 2 +- .../functional/Magento/FunctionalTest/Variable/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Vault/composer.json | 2 +- .../functional/Magento/FunctionalTest/Version/composer.json | 2 +- .../functional/Magento/FunctionalTest/Webapi/composer.json | 2 +- .../Magento/FunctionalTest/WebapiSecurity/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Weee/composer.json | 2 +- .../functional/Magento/FunctionalTest/Widget/composer.json | 2 +- .../functional/Magento/FunctionalTest/Wishlist/composer.json | 2 +- .../Magento/FunctionalTest/WishlistAnalytics/composer.json | 2 +- .../Magento/TestModuleIntegrationFromConfig/composer.json | 2 +- .../_files/Magento/TestModuleJoinDirectives/composer.json | 2 +- dev/tests/functional/composer.json | 2 +- .../integration/_files/Magento/TestModuleSample/composer.json | 2 +- .../testsuite/Magento/Deploy/_files/zoom1/composer.json | 2 +- .../testsuite/Magento/Deploy/_files/zoom2/composer.json | 2 +- .../testsuite/Magento/Deploy/_files/zoom3/composer.json | 2 +- .../Command/_files/root/app/code/Magento/A/composer.json | 2 +- .../Command/_files/root/app/code/Magento/B/composer.json | 2 +- .../Widget/_files/design/adminhtml/magento_basic/composer.json | 2 +- lib/internal/Magento/Framework/composer.json | 2 +- 257 files changed, 257 insertions(+), 257 deletions(-) diff --git a/app/code/Magento/AdminNotification/composer.json b/app/code/Magento/AdminNotification/composer.json index b8dba6f899645..0c2599be0088e 100644 --- a/app/code/Magento/AdminNotification/composer.json +++ b/app/code/Magento/AdminNotification/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "lib-libxml": "*", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/AdvancedPricingImportExport/composer.json b/app/code/Magento/AdvancedPricingImportExport/composer.json index 1660104953504..a4deb41d83ab9 100644 --- a/app/code/Magento/AdvancedPricingImportExport/composer.json +++ b/app/code/Magento/AdvancedPricingImportExport/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*", "magento/module-catalog-import-export": "100.3.*", diff --git a/app/code/Magento/Analytics/composer.json b/app/code/Magento/Analytics/composer.json index bdea53c445a34..ee39729f2ed83 100644 --- a/app/code/Magento/Analytics/composer.json +++ b/app/code/Magento/Analytics/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-analytics", "description": "N/A", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/module-backend": "100.3.*", "magento/module-config": "100.3.*", "magento/module-integration": "100.3.*", diff --git a/app/code/Magento/Authorization/composer.json b/app/code/Magento/Authorization/composer.json index 65e0d2a57e36d..06a802c7d465b 100644 --- a/app/code/Magento/Authorization/composer.json +++ b/app/code/Magento/Authorization/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*" }, diff --git a/app/code/Magento/Authorizenet/composer.json b/app/code/Magento/Authorizenet/composer.json index 89d3ba8045a40..fdbb509cb4e30 100644 --- a/app/code/Magento/Authorizenet/composer.json +++ b/app/code/Magento/Authorizenet/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/Backend/composer.json b/app/code/Magento/Backend/composer.json index fbbecb25efa50..a0a215a7d1981 100644 --- a/app/code/Magento/Backend/composer.json +++ b/app/code/Magento/Backend/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backup": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/Backup/composer.json b/app/code/Magento/Backup/composer.json index 5ae2ad06b7d01..cdb6851cdc052 100644 --- a/app/code/Magento/Backup/composer.json +++ b/app/code/Magento/Backup/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-cron": "100.3.*", diff --git a/app/code/Magento/Braintree/composer.json b/app/code/Magento/Braintree/composer.json index c14addf550dfb..73292bdd6ebaf 100644 --- a/app/code/Magento/Braintree/composer.json +++ b/app/code/Magento/Braintree/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "braintree/braintree_php": "3.22.0", "magento/framework": "100.3.*", "magento/magento-composer-installer": "*", diff --git a/app/code/Magento/Bundle/composer.json b/app/code/Magento/Bundle/composer.json index b31cc38562740..626d65fefb52b 100644 --- a/app/code/Magento/Bundle/composer.json +++ b/app/code/Magento/Bundle/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/BundleGraphQl/composer.json b/app/code/Magento/BundleGraphQl/composer.json index c813c73ba1f3d..97a9c95fd1bd0 100644 --- a/app/code/Magento/BundleGraphQl/composer.json +++ b/app/code/Magento/BundleGraphQl/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "version": "100.0.0-dev", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/module-catalog": "101.2.*", "magento/module-bundle": "100.3.*", "magento/module-catalog-graph-ql": "100.0.*", diff --git a/app/code/Magento/BundleImportExport/composer.json b/app/code/Magento/BundleImportExport/composer.json index 19aef21135d90..95d71f5399b5b 100644 --- a/app/code/Magento/BundleImportExport/composer.json +++ b/app/code/Magento/BundleImportExport/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-bundle": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/CacheInvalidate/composer.json b/app/code/Magento/CacheInvalidate/composer.json index 61a4d8831f117..85b1dc6db79ec 100644 --- a/app/code/Magento/CacheInvalidate/composer.json +++ b/app/code/Magento/CacheInvalidate/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-page-cache": "100.3.*" }, diff --git a/app/code/Magento/Captcha/composer.json b/app/code/Magento/Captcha/composer.json index 98a0d442c659d..75e690eef0035 100644 --- a/app/code/Magento/Captcha/composer.json +++ b/app/code/Magento/Captcha/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-checkout": "100.3.*", diff --git a/app/code/Magento/Catalog/composer.json b/app/code/Magento/Catalog/composer.json index 94d4f2d492bba..3d63b24844e73 100644 --- a/app/code/Magento/Catalog/composer.json +++ b/app/code/Magento/Catalog/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog-inventory": "100.3.*", diff --git a/app/code/Magento/CatalogAnalytics/composer.json b/app/code/Magento/CatalogAnalytics/composer.json index 35ebf21515875..bdea50ee47db5 100644 --- a/app/code/Magento/CatalogAnalytics/composer.json +++ b/app/code/Magento/CatalogAnalytics/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-catalog-analytics", "description": "N/A", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*" }, diff --git a/app/code/Magento/CatalogGraphQl/composer.json b/app/code/Magento/CatalogGraphQl/composer.json index 18501ee7d2ccf..d6cec08ab5ec2 100644 --- a/app/code/Magento/CatalogGraphQl/composer.json +++ b/app/code/Magento/CatalogGraphQl/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "version": "100.0.0-dev", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/module-eav": "100.3.*", "magento/module-catalog": "101.2.*", "magento/module-graph-ql": "100.0.*", diff --git a/app/code/Magento/CatalogImportExport/composer.json b/app/code/Magento/CatalogImportExport/composer.json index b86bb6be29b46..0620df4fdfd3e 100644 --- a/app/code/Magento/CatalogImportExport/composer.json +++ b/app/code/Magento/CatalogImportExport/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "ext-ctype": "*", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/CatalogInventory/composer.json b/app/code/Magento/CatalogInventory/composer.json index 1f8608192bbd3..bb5f170c0c433 100644 --- a/app/code/Magento/CatalogInventory/composer.json +++ b/app/code/Magento/CatalogInventory/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*", "magento/module-config": "100.3.*", diff --git a/app/code/Magento/CatalogRule/composer.json b/app/code/Magento/CatalogRule/composer.json index 66fe04c126d8f..5f47dc50dcefb 100644 --- a/app/code/Magento/CatalogRule/composer.json +++ b/app/code/Magento/CatalogRule/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/CatalogRuleConfigurable/composer.json b/app/code/Magento/CatalogRuleConfigurable/composer.json index e07209cfbc075..b8528aca05f33 100644 --- a/app/code/Magento/CatalogRuleConfigurable/composer.json +++ b/app/code/Magento/CatalogRuleConfigurable/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/magento-composer-installer": "*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json index 057117448e78f..3f2ce1e662ec5 100644 --- a/app/code/Magento/CatalogSearch/composer.json +++ b/app/code/Magento/CatalogSearch/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/CatalogUrlRewrite/composer.json b/app/code/Magento/CatalogUrlRewrite/composer.json index d5d9babce9cd1..7124eaef0a380 100644 --- a/app/code/Magento/CatalogUrlRewrite/composer.json +++ b/app/code/Magento/CatalogUrlRewrite/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/CatalogUrlRewriteGraphQl/composer.json b/app/code/Magento/CatalogUrlRewriteGraphQl/composer.json index 6de3783c1a9d2..b2d71591dee96 100644 --- a/app/code/Magento/CatalogUrlRewriteGraphQl/composer.json +++ b/app/code/Magento/CatalogUrlRewriteGraphQl/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "version": "100.0.0-dev", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*" }, "suggest": { diff --git a/app/code/Magento/CatalogWidget/composer.json b/app/code/Magento/CatalogWidget/composer.json index 11920e94e7e47..37a718b25e24a 100644 --- a/app/code/Magento/CatalogWidget/composer.json +++ b/app/code/Magento/CatalogWidget/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/Checkout/composer.json b/app/code/Magento/Checkout/composer.json index 1fad0ab9986ea..2c90b5dfa7bab 100644 --- a/app/code/Magento/Checkout/composer.json +++ b/app/code/Magento/Checkout/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/CheckoutAgreements/composer.json b/app/code/Magento/CheckoutAgreements/composer.json index 74df969951219..fabb496b8f7ea 100644 --- a/app/code/Magento/CheckoutAgreements/composer.json +++ b/app/code/Magento/CheckoutAgreements/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-checkout": "100.3.*", diff --git a/app/code/Magento/Cms/composer.json b/app/code/Magento/Cms/composer.json index d6842ccc67169..780d913b417d8 100644 --- a/app/code/Magento/Cms/composer.json +++ b/app/code/Magento/Cms/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/CmsUrlRewrite/composer.json b/app/code/Magento/CmsUrlRewrite/composer.json index 675cd8fe8f466..16d2f88d83887 100644 --- a/app/code/Magento/CmsUrlRewrite/composer.json +++ b/app/code/Magento/CmsUrlRewrite/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-cms": "101.2.*", "magento/module-store": "100.3.*", diff --git a/app/code/Magento/CmsUrlRewriteGraphQl/composer.json b/app/code/Magento/CmsUrlRewriteGraphQl/composer.json index 2b8980ba054ea..72ac8c3454b8f 100644 --- a/app/code/Magento/CmsUrlRewriteGraphQl/composer.json +++ b/app/code/Magento/CmsUrlRewriteGraphQl/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "version": "100.0.0-dev", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*" }, diff --git a/app/code/Magento/Config/composer.json b/app/code/Magento/Config/composer.json index 52f257311e146..1a34c927dc926 100644 --- a/app/code/Magento/Config/composer.json +++ b/app/code/Magento/Config/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-cron": "100.3.*", diff --git a/app/code/Magento/ConfigurableImportExport/composer.json b/app/code/Magento/ConfigurableImportExport/composer.json index 1de5024f61981..1c4f22539f401 100644 --- a/app/code/Magento/ConfigurableImportExport/composer.json +++ b/app/code/Magento/ConfigurableImportExport/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*", "magento/module-catalog-import-export": "100.3.*", diff --git a/app/code/Magento/ConfigurableProduct/composer.json b/app/code/Magento/ConfigurableProduct/composer.json index f06afe07d7b7f..b1137aac51dc0 100644 --- a/app/code/Magento/ConfigurableProduct/composer.json +++ b/app/code/Magento/ConfigurableProduct/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/ConfigurableProductGraphQl/composer.json b/app/code/Magento/ConfigurableProductGraphQl/composer.json index 58881fedd63ea..9412622a1b096 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/composer.json +++ b/app/code/Magento/ConfigurableProductGraphQl/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "version": "100.0.0-dev", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/module-catalog": "101.2.*", "magento/module-configurable-product": "100.3.*", "magento/module-catalog-graph-ql": "100.0.*", diff --git a/app/code/Magento/ConfigurableProductSales/composer.json b/app/code/Magento/ConfigurableProductSales/composer.json index 4a1d4732b9967..57c18e733b2f1 100644 --- a/app/code/Magento/ConfigurableProductSales/composer.json +++ b/app/code/Magento/ConfigurableProductSales/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*", "magento/module-sales": "100.3.*", diff --git a/app/code/Magento/Contact/composer.json b/app/code/Magento/Contact/composer.json index 688089adaae1e..08803d57c386b 100644 --- a/app/code/Magento/Contact/composer.json +++ b/app/code/Magento/Contact/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-cms": "101.2.*", "magento/module-config": "100.3.*", diff --git a/app/code/Magento/Cookie/composer.json b/app/code/Magento/Cookie/composer.json index 7b1c04461766a..97b3a6d5a901f 100644 --- a/app/code/Magento/Cookie/composer.json +++ b/app/code/Magento/Cookie/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-store": "100.3.*" }, diff --git a/app/code/Magento/Cron/composer.json b/app/code/Magento/Cron/composer.json index a3b87649f3c77..6e7c21ea9de1e 100644 --- a/app/code/Magento/Cron/composer.json +++ b/app/code/Magento/Cron/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-store": "100.3.*" }, diff --git a/app/code/Magento/CurrencySymbol/composer.json b/app/code/Magento/CurrencySymbol/composer.json index deb971933f9fa..29043ca70841b 100644 --- a/app/code/Magento/CurrencySymbol/composer.json +++ b/app/code/Magento/CurrencySymbol/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-config": "100.3.*", diff --git a/app/code/Magento/Customer/composer.json b/app/code/Magento/Customer/composer.json index 9dbac36146be1..4b4a49f5d99fb 100644 --- a/app/code/Magento/Customer/composer.json +++ b/app/code/Magento/Customer/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-authorization": "100.3.*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/CustomerAnalytics/composer.json b/app/code/Magento/CustomerAnalytics/composer.json index 199c9b9a1927f..286e9d4f7e6e8 100644 --- a/app/code/Magento/CustomerAnalytics/composer.json +++ b/app/code/Magento/CustomerAnalytics/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-customer-analytics", "description": "N/A", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-customer": "100.3.*" }, diff --git a/app/code/Magento/CustomerGraphQl/composer.json b/app/code/Magento/CustomerGraphQl/composer.json index 8d8e18fab9388..6bac87d04ad34 100644 --- a/app/code/Magento/CustomerGraphQl/composer.json +++ b/app/code/Magento/CustomerGraphQl/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "version": "100.0.0-dev", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/module-customer": "100.2.*", "magento/module-graph-ql": "100.0.*", "magento/framework": "100.3.*" diff --git a/app/code/Magento/CustomerImportExport/composer.json b/app/code/Magento/CustomerImportExport/composer.json index 4bb739e526194..87ef467219958 100644 --- a/app/code/Magento/CustomerImportExport/composer.json +++ b/app/code/Magento/CustomerImportExport/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-customer": "100.3.*", diff --git a/app/code/Magento/Deploy/composer.json b/app/code/Magento/Deploy/composer.json index 8f44709594e00..d2969ada0f0a3 100644 --- a/app/code/Magento/Deploy/composer.json +++ b/app/code/Magento/Deploy/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-config": "100.3.*", "magento/module-require-js": "100.3.*", diff --git a/app/code/Magento/Developer/composer.json b/app/code/Magento/Developer/composer.json index 4905fa22b648b..bb6405cb3342b 100644 --- a/app/code/Magento/Developer/composer.json +++ b/app/code/Magento/Developer/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-config": "100.3.*", "magento/module-store": "100.3.*" diff --git a/app/code/Magento/Dhl/composer.json b/app/code/Magento/Dhl/composer.json index 4f61112fbd974..4228f0a8fbf1e 100644 --- a/app/code/Magento/Dhl/composer.json +++ b/app/code/Magento/Dhl/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "lib-libxml": "*", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/Directory/composer.json b/app/code/Magento/Directory/composer.json index 5cdeeea0624ac..7b1dc0775d6db 100644 --- a/app/code/Magento/Directory/composer.json +++ b/app/code/Magento/Directory/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "lib-libxml": "*", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/Downloadable/composer.json b/app/code/Magento/Downloadable/composer.json index 99aee584e103b..46549d4ad4b21 100644 --- a/app/code/Magento/Downloadable/composer.json +++ b/app/code/Magento/Downloadable/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/DownloadableGraphQl/composer.json b/app/code/Magento/DownloadableGraphQl/composer.json index ae3ac33de1b71..f3d0dfac26a2a 100644 --- a/app/code/Magento/DownloadableGraphQl/composer.json +++ b/app/code/Magento/DownloadableGraphQl/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "version": "100.0.0-dev", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/module-catalog": "101.2.*", "magento/module-downloadable": "100.3.*", "magento/module-catalog-graph-ql": "100.0.*", diff --git a/app/code/Magento/DownloadableImportExport/composer.json b/app/code/Magento/DownloadableImportExport/composer.json index 534da4210ae1c..4784d4b9f7600 100644 --- a/app/code/Magento/DownloadableImportExport/composer.json +++ b/app/code/Magento/DownloadableImportExport/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*", "magento/module-catalog-import-export": "100.3.*", diff --git a/app/code/Magento/Eav/composer.json b/app/code/Magento/Eav/composer.json index e6657535ecac1..6395aa4a2b445 100644 --- a/app/code/Magento/Eav/composer.json +++ b/app/code/Magento/Eav/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/EavGraphQl/composer.json b/app/code/Magento/EavGraphQl/composer.json index 226300c4e70e6..fe425ac12dbba 100644 --- a/app/code/Magento/EavGraphQl/composer.json +++ b/app/code/Magento/EavGraphQl/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "version": "100.0.0-dev", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/module-graph-ql": "100.0.*", "magento/framework": "100.3.*" }, diff --git a/app/code/Magento/Email/composer.json b/app/code/Magento/Email/composer.json index ad03fd37bcd76..490568fd2b79c 100644 --- a/app/code/Magento/Email/composer.json +++ b/app/code/Magento/Email/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-cms": "101.2.*", diff --git a/app/code/Magento/EncryptionKey/composer.json b/app/code/Magento/EncryptionKey/composer.json index 0f69af3cc1de9..72c6c5432887a 100644 --- a/app/code/Magento/EncryptionKey/composer.json +++ b/app/code/Magento/EncryptionKey/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-config": "100.3.*" diff --git a/app/code/Magento/Fedex/composer.json b/app/code/Magento/Fedex/composer.json index 4135887fc51e4..b5f9996cf1576 100644 --- a/app/code/Magento/Fedex/composer.json +++ b/app/code/Magento/Fedex/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "lib-libxml": "*", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/GiftMessage/composer.json b/app/code/Magento/GiftMessage/composer.json index e46aa25c4027b..bca2ba677ccd4 100644 --- a/app/code/Magento/GiftMessage/composer.json +++ b/app/code/Magento/GiftMessage/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/GoogleAdwords/composer.json b/app/code/Magento/GoogleAdwords/composer.json index 6d12aa26acdee..9f1619dfd7669 100644 --- a/app/code/Magento/GoogleAdwords/composer.json +++ b/app/code/Magento/GoogleAdwords/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-sales": "100.3.*", "magento/module-store": "100.3.*" diff --git a/app/code/Magento/GoogleAnalytics/composer.json b/app/code/Magento/GoogleAnalytics/composer.json index 1e1eb5b99fad4..3f7e49ddd47ac 100644 --- a/app/code/Magento/GoogleAnalytics/composer.json +++ b/app/code/Magento/GoogleAnalytics/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-cookie": "100.3.*", "magento/module-sales": "100.3.*", diff --git a/app/code/Magento/GoogleOptimizer/composer.json b/app/code/Magento/GoogleOptimizer/composer.json index d86e804f3851d..8260aaeff3da5 100644 --- a/app/code/Magento/GoogleOptimizer/composer.json +++ b/app/code/Magento/GoogleOptimizer/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/GraphQl/composer.json b/app/code/Magento/GraphQl/composer.json index 249f0f026a489..58cf9c567d716 100644 --- a/app/code/Magento/GraphQl/composer.json +++ b/app/code/Magento/GraphQl/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "version": "100.0.0-dev", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/module-authorization": "100.3.*", "magento/module-store": "100.3.*", "magento/module-eav": "100.3.*", diff --git a/app/code/Magento/GroupedImportExport/composer.json b/app/code/Magento/GroupedImportExport/composer.json index 8c03d3035eca9..fb65e445f39ad 100644 --- a/app/code/Magento/GroupedImportExport/composer.json +++ b/app/code/Magento/GroupedImportExport/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*", "magento/module-catalog-import-export": "100.3.*", diff --git a/app/code/Magento/GroupedProduct/composer.json b/app/code/Magento/GroupedProduct/composer.json index 7dd450c857129..875d5a6a98442 100644 --- a/app/code/Magento/GroupedProduct/composer.json +++ b/app/code/Magento/GroupedProduct/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/GroupedProductGraphQl/composer.json b/app/code/Magento/GroupedProductGraphQl/composer.json index d33ef287cb816..892d0ac1b3e6c 100644 --- a/app/code/Magento/GroupedProductGraphQl/composer.json +++ b/app/code/Magento/GroupedProductGraphQl/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "version": "100.0.0-dev", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/module-catalog": "101.2.*", "magento/module-grouped-product": "100.3.*", "magento/module-catalog-graph-ql": "100.0.*", diff --git a/app/code/Magento/ImportExport/composer.json b/app/code/Magento/ImportExport/composer.json index f54981cdb8bb7..542b1bcc08be1 100644 --- a/app/code/Magento/ImportExport/composer.json +++ b/app/code/Magento/ImportExport/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "ext-ctype": "*", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/Indexer/composer.json b/app/code/Magento/Indexer/composer.json index 82b041b2073af..641fb0ffe3ea1 100644 --- a/app/code/Magento/Indexer/composer.json +++ b/app/code/Magento/Indexer/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*" }, diff --git a/app/code/Magento/InstantPurchase/composer.json b/app/code/Magento/InstantPurchase/composer.json index cf1dc0f2b5f87..c47c3fdfcf507 100644 --- a/app/code/Magento/InstantPurchase/composer.json +++ b/app/code/Magento/InstantPurchase/composer.json @@ -8,7 +8,7 @@ "AFL-3.0" ], "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/module-store": "100.3.*", "magento/module-catalog": "102.0.*", "magento/module-customer": "101.0.*", diff --git a/app/code/Magento/Integration/composer.json b/app/code/Magento/Integration/composer.json index 662112431ad08..83a2eb15c484f 100644 --- a/app/code/Magento/Integration/composer.json +++ b/app/code/Magento/Integration/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-authorization": "100.3.*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/LayeredNavigation/composer.json b/app/code/Magento/LayeredNavigation/composer.json index 8239a80529b3e..95a53de2855c5 100644 --- a/app/code/Magento/LayeredNavigation/composer.json +++ b/app/code/Magento/LayeredNavigation/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*", "magento/module-config": "100.3.*" diff --git a/app/code/Magento/Marketplace/composer.json b/app/code/Magento/Marketplace/composer.json index bcaf453cd73b9..6d491bd71bda7 100644 --- a/app/code/Magento/Marketplace/composer.json +++ b/app/code/Magento/Marketplace/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*" }, diff --git a/app/code/Magento/MediaStorage/composer.json b/app/code/Magento/MediaStorage/composer.json index 085719974ddea..2a56717852215 100644 --- a/app/code/Magento/MediaStorage/composer.json +++ b/app/code/Magento/MediaStorage/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-config": "100.3.*", diff --git a/app/code/Magento/Msrp/composer.json b/app/code/Magento/Msrp/composer.json index 7d7059ecd5e9b..b04d9537271dc 100644 --- a/app/code/Magento/Msrp/composer.json +++ b/app/code/Magento/Msrp/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*", "magento/module-downloadable": "100.3.*", diff --git a/app/code/Magento/Multishipping/composer.json b/app/code/Magento/Multishipping/composer.json index b483c4e3b0431..74a77101b8910 100644 --- a/app/code/Magento/Multishipping/composer.json +++ b/app/code/Magento/Multishipping/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-checkout": "100.3.*", "magento/module-customer": "100.3.*", diff --git a/app/code/Magento/NewRelicReporting/composer.json b/app/code/Magento/NewRelicReporting/composer.json index 43d2b69816a26..a4dea1ab3b99f 100644 --- a/app/code/Magento/NewRelicReporting/composer.json +++ b/app/code/Magento/NewRelicReporting/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/magento-composer-installer": "*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/Newsletter/composer.json b/app/code/Magento/Newsletter/composer.json index eaa4f37a1c540..e25c80ff2ffa6 100644 --- a/app/code/Magento/Newsletter/composer.json +++ b/app/code/Magento/Newsletter/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-cms": "101.2.*", diff --git a/app/code/Magento/OfflinePayments/composer.json b/app/code/Magento/OfflinePayments/composer.json index d9791f9f63428..f71872b8da7da 100644 --- a/app/code/Magento/OfflinePayments/composer.json +++ b/app/code/Magento/OfflinePayments/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-checkout": "100.3.*", "magento/module-payment": "100.3.*" diff --git a/app/code/Magento/OfflineShipping/composer.json b/app/code/Magento/OfflineShipping/composer.json index d07f9303137c2..5c6a91eeb9d33 100644 --- a/app/code/Magento/OfflineShipping/composer.json +++ b/app/code/Magento/OfflineShipping/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/PageCache/composer.json b/app/code/Magento/PageCache/composer.json index c4232235f5dab..76e46e45fe5de 100644 --- a/app/code/Magento/PageCache/composer.json +++ b/app/code/Magento/PageCache/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-config": "100.3.*", diff --git a/app/code/Magento/Payment/composer.json b/app/code/Magento/Payment/composer.json index c8b4266f3116d..eedd4b85c6cb2 100644 --- a/app/code/Magento/Payment/composer.json +++ b/app/code/Magento/Payment/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-checkout": "100.3.*", "magento/module-config": "100.3.*", diff --git a/app/code/Magento/Paypal/composer.json b/app/code/Magento/Paypal/composer.json index 65a6952e55600..64b195e69a43e 100644 --- a/app/code/Magento/Paypal/composer.json +++ b/app/code/Magento/Paypal/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "lib-libxml": "*", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/Persistent/composer.json b/app/code/Magento/Persistent/composer.json index 83a9655c6a647..61ab11de3006f 100644 --- a/app/code/Magento/Persistent/composer.json +++ b/app/code/Magento/Persistent/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-checkout": "100.3.*", "magento/module-cron": "100.3.*", diff --git a/app/code/Magento/ProductAlert/composer.json b/app/code/Magento/ProductAlert/composer.json index be3c30aa94626..fc4c9f7b322f7 100644 --- a/app/code/Magento/ProductAlert/composer.json +++ b/app/code/Magento/ProductAlert/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/ProductVideo/composer.json b/app/code/Magento/ProductVideo/composer.json index 5292eaab2311f..11fe45be81b5f 100644 --- a/app/code/Magento/ProductVideo/composer.json +++ b/app/code/Magento/ProductVideo/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/magento-composer-installer": "*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/Quote/composer.json b/app/code/Magento/Quote/composer.json index 760c4267ddd9d..1a90a9f6f1441 100644 --- a/app/code/Magento/Quote/composer.json +++ b/app/code/Magento/Quote/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-authorization": "100.3.*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/QuoteAnalytics/composer.json b/app/code/Magento/QuoteAnalytics/composer.json index c683a5e25c889..01a76a3f4dcc1 100644 --- a/app/code/Magento/QuoteAnalytics/composer.json +++ b/app/code/Magento/QuoteAnalytics/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-quote-analytics", "description": "N/A", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-quote": "100.3.*" }, diff --git a/app/code/Magento/ReleaseNotification/composer.json b/app/code/Magento/ReleaseNotification/composer.json index 9e728b1e01729..0262b393cd375 100644 --- a/app/code/Magento/ReleaseNotification/composer.json +++ b/app/code/Magento/ReleaseNotification/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-release-notification", "description": "N/A", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/module-user": "101.0.*", "magento/module-backend": "100.3.*", "magento/module-ui": "100.3.*", diff --git a/app/code/Magento/Reports/composer.json b/app/code/Magento/Reports/composer.json index f1e6719a59d0b..eedf5b1eb4db0 100644 --- a/app/code/Magento/Reports/composer.json +++ b/app/code/Magento/Reports/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/RequireJs/composer.json b/app/code/Magento/RequireJs/composer.json index d54dfeafc6f74..e886804814744 100644 --- a/app/code/Magento/RequireJs/composer.json +++ b/app/code/Magento/RequireJs/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*" }, "type": "magento2-module", diff --git a/app/code/Magento/Review/composer.json b/app/code/Magento/Review/composer.json index a4f12e758ac83..d0666716ea01e 100644 --- a/app/code/Magento/Review/composer.json +++ b/app/code/Magento/Review/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/ReviewAnalytics/composer.json b/app/code/Magento/ReviewAnalytics/composer.json index 9f0b58b529a25..e7054b9cac232 100644 --- a/app/code/Magento/ReviewAnalytics/composer.json +++ b/app/code/Magento/ReviewAnalytics/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-review-analytics", "description": "N/A", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-review": "100.3.*" }, diff --git a/app/code/Magento/Robots/composer.json b/app/code/Magento/Robots/composer.json index b04f3bff15fa2..da0cfe4f6aa85 100644 --- a/app/code/Magento/Robots/composer.json +++ b/app/code/Magento/Robots/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-store": "100.3.*" }, diff --git a/app/code/Magento/Rss/composer.json b/app/code/Magento/Rss/composer.json index 7fe788c0494ae..ddd1a7f511c5d 100644 --- a/app/code/Magento/Rss/composer.json +++ b/app/code/Magento/Rss/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-customer": "100.3.*", diff --git a/app/code/Magento/Rule/composer.json b/app/code/Magento/Rule/composer.json index 2a2aff2dc77f0..946cd10c3db3f 100644 --- a/app/code/Magento/Rule/composer.json +++ b/app/code/Magento/Rule/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "lib-libxml": "*", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/Sales/composer.json b/app/code/Magento/Sales/composer.json index 1797a3122c32e..5859413378d09 100644 --- a/app/code/Magento/Sales/composer.json +++ b/app/code/Magento/Sales/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-authorization": "100.3.*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/SalesAnalytics/composer.json b/app/code/Magento/SalesAnalytics/composer.json index e9d1eb7084925..86fa828970729 100644 --- a/app/code/Magento/SalesAnalytics/composer.json +++ b/app/code/Magento/SalesAnalytics/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-sales-analytics", "description": "N/A", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-sales": "100.3.*" }, diff --git a/app/code/Magento/SalesInventory/composer.json b/app/code/Magento/SalesInventory/composer.json index 2150f0773e717..90a4e4e96098f 100644 --- a/app/code/Magento/SalesInventory/composer.json +++ b/app/code/Magento/SalesInventory/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*", "magento/module-catalog-inventory": "100.3.*", diff --git a/app/code/Magento/SalesRule/composer.json b/app/code/Magento/SalesRule/composer.json index 44f5a78954618..624f841407d2f 100644 --- a/app/code/Magento/SalesRule/composer.json +++ b/app/code/Magento/SalesRule/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/SalesSequence/composer.json b/app/code/Magento/SalesSequence/composer.json index 37b562420383d..95c2a56f2dc29 100644 --- a/app/code/Magento/SalesSequence/composer.json +++ b/app/code/Magento/SalesSequence/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*" }, "type": "magento2-module", diff --git a/app/code/Magento/SampleData/composer.json b/app/code/Magento/SampleData/composer.json index 0109bab4d9240..1235f672c944b 100644 --- a/app/code/Magento/SampleData/composer.json +++ b/app/code/Magento/SampleData/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*" }, "suggest": { diff --git a/app/code/Magento/Search/composer.json b/app/code/Magento/Search/composer.json index 192e2c843a7b8..ab35d3fbdf86c 100644 --- a/app/code/Magento/Search/composer.json +++ b/app/code/Magento/Search/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog-search": "100.3.*", diff --git a/app/code/Magento/Security/composer.json b/app/code/Magento/Security/composer.json index e9b646cc5ca76..64a7ee33c5a08 100644 --- a/app/code/Magento/Security/composer.json +++ b/app/code/Magento/Security/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-store": "100.3.*", diff --git a/app/code/Magento/SendFriend/composer.json b/app/code/Magento/SendFriend/composer.json index ab01ba4360e8d..154f180c0d286 100644 --- a/app/code/Magento/SendFriend/composer.json +++ b/app/code/Magento/SendFriend/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*", "magento/module-customer": "100.3.*", diff --git a/app/code/Magento/Shipping/composer.json b/app/code/Magento/Shipping/composer.json index 7d33f54eee037..fe306fb908c9b 100644 --- a/app/code/Magento/Shipping/composer.json +++ b/app/code/Magento/Shipping/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "ext-gd": "*", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/Signifyd/composer.json b/app/code/Magento/Signifyd/composer.json index 59326a48f3e85..df0817be2ba6d 100644 --- a/app/code/Magento/Signifyd/composer.json +++ b/app/code/Magento/Signifyd/composer.json @@ -14,7 +14,7 @@ "magento/module-payment": "100.3.*", "magento/module-sales": "100.3.*", "magento/module-store": "100.3.*", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0", }, "suggest": { "magento/module-config": "100.3.*" diff --git a/app/code/Magento/Sitemap/composer.json b/app/code/Magento/Sitemap/composer.json index fe8d2d1919e5a..0a56f752d5a85 100644 --- a/app/code/Magento/Sitemap/composer.json +++ b/app/code/Magento/Sitemap/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json index a8e3dbc5d1357..e84847f274c4b 100644 --- a/app/code/Magento/Store/composer.json +++ b/app/code/Magento/Store/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*", "magento/module-config": "100.3.*", diff --git a/app/code/Magento/Swagger/composer.json b/app/code/Magento/Swagger/composer.json index 5ea14336944d9..8f15922759653 100644 --- a/app/code/Magento/Swagger/composer.json +++ b/app/code/Magento/Swagger/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*" }, "type": "magento2-module", diff --git a/app/code/Magento/Swatches/composer.json b/app/code/Magento/Swatches/composer.json index 5e63cde9eb160..20449281b8ffe 100644 --- a/app/code/Magento/Swatches/composer.json +++ b/app/code/Magento/Swatches/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/SwatchesGraphQl/composer.json b/app/code/Magento/SwatchesGraphQl/composer.json index 4efdc678f3239..93dee1be6e6f4 100644 --- a/app/code/Magento/SwatchesGraphQl/composer.json +++ b/app/code/Magento/SwatchesGraphQl/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "version": "100.0.0-dev", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*" }, "suggest": { diff --git a/app/code/Magento/SwatchesLayeredNavigation/composer.json b/app/code/Magento/SwatchesLayeredNavigation/composer.json index 7bc4053df84f7..ac690c1420f75 100644 --- a/app/code/Magento/SwatchesLayeredNavigation/composer.json +++ b/app/code/Magento/SwatchesLayeredNavigation/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/magento-composer-installer": "*" }, diff --git a/app/code/Magento/Tax/composer.json b/app/code/Magento/Tax/composer.json index 944823ef600ab..0208a199c930f 100644 --- a/app/code/Magento/Tax/composer.json +++ b/app/code/Magento/Tax/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/TaxGraphQl/composer.json b/app/code/Magento/TaxGraphQl/composer.json index ca65d0fa3cde4..fd4ad75825b19 100644 --- a/app/code/Magento/TaxGraphQl/composer.json +++ b/app/code/Magento/TaxGraphQl/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "version": "100.0.0-dev", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*" }, "suggest": { diff --git a/app/code/Magento/TaxImportExport/composer.json b/app/code/Magento/TaxImportExport/composer.json index 69d6cc4162f8d..3d4be48a8a44e 100644 --- a/app/code/Magento/TaxImportExport/composer.json +++ b/app/code/Magento/TaxImportExport/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-directory": "100.3.*", diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json index 89c543f7f3c15..5a8b0cd43c345 100644 --- a/app/code/Magento/Theme/composer.json +++ b/app/code/Magento/Theme/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-cms": "101.2.*", diff --git a/app/code/Magento/Tinymce3/composer.json b/app/code/Magento/Tinymce3/composer.json index e4088890b807b..e7c8c8dd96dba 100644 --- a/app/code/Magento/Tinymce3/composer.json +++ b/app/code/Magento/Tinymce3/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-tinymce-3", "description": "N/A", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-ui": "100.3.*", "magento/module-variable": "100.3.*", diff --git a/app/code/Magento/Translation/composer.json b/app/code/Magento/Translation/composer.json index 2fc619e36bce8..58f2158652d5f 100644 --- a/app/code/Magento/Translation/composer.json +++ b/app/code/Magento/Translation/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-developer": "100.3.*", diff --git a/app/code/Magento/Ui/composer.json b/app/code/Magento/Ui/composer.json index e9ace8bb159c0..9b3cf2265e91c 100644 --- a/app/code/Magento/Ui/composer.json +++ b/app/code/Magento/Ui/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-authorization": "100.3.*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/Ups/composer.json b/app/code/Magento/Ups/composer.json index 06b729c961c5a..0d7a0a6cd5c43 100644 --- a/app/code/Magento/Ups/composer.json +++ b/app/code/Magento/Ups/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog-inventory": "100.3.*", diff --git a/app/code/Magento/UrlRewrite/composer.json b/app/code/Magento/UrlRewrite/composer.json index 1944531ce4468..063498fd332f3 100644 --- a/app/code/Magento/UrlRewrite/composer.json +++ b/app/code/Magento/UrlRewrite/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/UrlRewriteGraphQl/composer.json b/app/code/Magento/UrlRewriteGraphQl/composer.json index 9a73104893365..a93d2b68e8b4d 100644 --- a/app/code/Magento/UrlRewriteGraphQl/composer.json +++ b/app/code/Magento/UrlRewriteGraphQl/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "version": "100.0.0-dev", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-graph-ql": "100.0.*", "magento/module-url-rewrite": "100.3.*", diff --git a/app/code/Magento/User/composer.json b/app/code/Magento/User/composer.json index 5709986a0c2fb..498760362c8a8 100644 --- a/app/code/Magento/User/composer.json +++ b/app/code/Magento/User/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-authorization": "100.3.*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/Usps/composer.json b/app/code/Magento/Usps/composer.json index 91697a1d2f15a..33a1fc5e7b891 100644 --- a/app/code/Magento/Usps/composer.json +++ b/app/code/Magento/Usps/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "lib-libxml": "*", "magento/framework": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/Variable/composer.json b/app/code/Magento/Variable/composer.json index 5702c93e4fe5d..8dbfbbeb7b909 100644 --- a/app/code/Magento/Variable/composer.json +++ b/app/code/Magento/Variable/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-store": "100.3.*", diff --git a/app/code/Magento/Vault/composer.json b/app/code/Magento/Vault/composer.json index 4474d8ce03d9d..c489b8fc0a842 100644 --- a/app/code/Magento/Vault/composer.json +++ b/app/code/Magento/Vault/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-checkout": "100.3.*", "magento/module-customer": "100.3.*", diff --git a/app/code/Magento/Version/composer.json b/app/code/Magento/Version/composer.json index 91df7db9d801c..fe13945e55d21 100644 --- a/app/code/Magento/Version/composer.json +++ b/app/code/Magento/Version/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*" }, "type": "magento2-module", diff --git a/app/code/Magento/Webapi/composer.json b/app/code/Magento/Webapi/composer.json index 4d6046c904e31..5e008cad8e78b 100644 --- a/app/code/Magento/Webapi/composer.json +++ b/app/code/Magento/Webapi/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-authorization": "100.3.*", "magento/module-backend": "100.3.*", diff --git a/app/code/Magento/WebapiSecurity/composer.json b/app/code/Magento/WebapiSecurity/composer.json index 2366be72794c8..7ddb3afc56001 100644 --- a/app/code/Magento/WebapiSecurity/composer.json +++ b/app/code/Magento/WebapiSecurity/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-webapi": "100.3.*" }, diff --git a/app/code/Magento/Weee/composer.json b/app/code/Magento/Weee/composer.json index 3e6617c79f702..b14c2cf246463 100644 --- a/app/code/Magento/Weee/composer.json +++ b/app/code/Magento/Weee/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/WeeeGraphQl/composer.json b/app/code/Magento/WeeeGraphQl/composer.json index cf851a118c86c..cc1966dcf6ee0 100644 --- a/app/code/Magento/WeeeGraphQl/composer.json +++ b/app/code/Magento/WeeeGraphQl/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "version": "100.0.0-dev", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*" }, "suggest": { diff --git a/app/code/Magento/Widget/composer.json b/app/code/Magento/Widget/composer.json index 0b4007d4a250a..7012b0397f1ce 100644 --- a/app/code/Magento/Widget/composer.json +++ b/app/code/Magento/Widget/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/Wishlist/composer.json b/app/code/Magento/Wishlist/composer.json index b6a887ec18b63..860fe09250dcf 100644 --- a/app/code/Magento/Wishlist/composer.json +++ b/app/code/Magento/Wishlist/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-backend": "100.3.*", "magento/module-catalog": "101.2.*", diff --git a/app/code/Magento/WishlistAnalytics/composer.json b/app/code/Magento/WishlistAnalytics/composer.json index 8a3fb3a5189d0..c04ecc0521c97 100644 --- a/app/code/Magento/WishlistAnalytics/composer.json +++ b/app/code/Magento/WishlistAnalytics/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-wishlist-analytics", "description": "N/A", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/module-wishlist": "100.3.*" }, diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdminNotification/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdminNotification/composer.json index c6ec48b2930e5..49a59426cfa6d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdminNotification/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdminNotification/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedPricingImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedPricingImportExport/composer.json index 4c0832605ae1d..96be03e146356 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedPricingImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedPricingImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/composer.json index 9245dc6e40766..cb59843c9cba8 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorization/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorization/composer.json index 4e78766d9d135..2eab99a968a9a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorization/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorization/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorizenet/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorizenet/composer.json index 80d7737565277..06dce68805cd9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorizenet/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorizenet/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/composer.json index 2d2dd01724f81..b2a99b07f0255 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backup": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backup/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backup/composer.json index a77c84d925563..c6e51064c592f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backup/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backup/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Braintree/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Braintree/composer.json index e91cba389bbff..d3a13786a0a9d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Braintree/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Braintree/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/composer.json index 4a724336f1d2c..f2dd821d4fc36 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/BundleImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/BundleImportExport/composer.json index 1653aebe65ded..fd79ec03d4ea9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/BundleImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/BundleImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-bundle": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CacheInvalidate/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CacheInvalidate/composer.json index 3d8072140d268..f59864d2a14ea 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CacheInvalidate/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CacheInvalidate/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-page-cache": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Captcha/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Captcha/composer.json index 6b5beca7862e1..0297dbb343bcb 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Captcha/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Captcha/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/composer.json index 3b9967130fe18..5ca0adbc4d6e3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogAnalytics/composer.json index b742218731f84..cce1015d0d2e5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogImportExport/composer.json index 22866e9abd2c1..b2b0b3965429a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogInventory/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogInventory/composer.json index ba124db346ae5..432acba351bc3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogInventory/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogInventory/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/composer.json index b478cb58583b5..49b2aeb653fb1 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRuleConfigurable/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRuleConfigurable/composer.json index b232f1e8563b0..62be67eaed6da 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRuleConfigurable/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRuleConfigurable/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/composer.json index 50e466e1185ca..0dca452843b18 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogUrlRewrite/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogUrlRewrite/composer.json index 771e0385eccbc..a6b42de511466 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogUrlRewrite/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogUrlRewrite/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogWidget/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogWidget/composer.json index 1427c1af64b02..5550db57606ba 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogWidget/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogWidget/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/composer.json index 2a19649ad5202..5f7d90fb27a58 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CheckoutAgreements/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CheckoutAgreements/composer.json index 8860639e22883..fe061803b297b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CheckoutAgreements/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CheckoutAgreements/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/composer.json index c1d868e742226..07aa529e45e14 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CmsUrlRewrite/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CmsUrlRewrite/composer.json index c4ad8b0dc2f71..7c35ddafd671d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CmsUrlRewrite/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CmsUrlRewrite/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-cms": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/composer.json index b556ce773a6d3..4f3c721c582b1 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableImportExport/composer.json index b512f02910419..2d8699d4999d5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/composer.json index 93144b56d2fd9..3216f2e9e1f94 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductSales/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductSales/composer.json index 36389d2cc51bb..629ead23ae981 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductSales/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductSales/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Contact/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Contact/composer.json index 928012f706a4a..b77a865b04de1 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Contact/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Contact/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-cms": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cookie/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cookie/composer.json index 9aff0ad424117..4d55d54479092 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cookie/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cookie/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-store": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cron/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cron/composer.json index a4136569d26fc..ad913508c5cbb 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cron/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cron/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-store": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CurrencySymbol/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CurrencySymbol/composer.json index f11a1371b395a..335cee4939672 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CurrencySymbol/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CurrencySymbol/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/composer.json index e75cac61cb228..e6e178fbcd163 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerAnalytics/composer.json index 84a73e12eb4ff..6082e25ee87ac 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-customer": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerImportExport/composer.json index a63a0cc71af20..09caca0289949 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Deploy/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Deploy/composer.json index 49a9b5333133e..6cc25c9975ac9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Deploy/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Deploy/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-config": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Developer/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Developer/composer.json index ec19ec7de8e37..d20bf30c17289 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Developer/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Developer/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-config": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Dhl/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Dhl/composer.json index 6ce6995f55137..9d2da35038bfe 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Dhl/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Dhl/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Directory/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Directory/composer.json index 30a6dccdd6876..8262f404e93a3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Directory/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Directory/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/composer.json index 400738980fd06..d1972e5d5dd9a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/DownloadableImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/DownloadableImportExport/composer.json index 5078e028732b4..2c3b8fd9ce566 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/DownloadableImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/DownloadableImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Eav/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Eav/composer.json index e14cf4a78bc3f..06db9b63d7387 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Eav/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Eav/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Email/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Email/composer.json index 6627c6b77fd0d..e95fc4ca907e3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Email/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Email/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/EncryptionKey/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/EncryptionKey/composer.json index 371c1f30b8dab..0252e03b31808 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/EncryptionKey/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/EncryptionKey/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Fedex/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Fedex/composer.json index 1cf32f0772260..5cf3ea9132e2a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Fedex/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Fedex/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GiftMessage/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GiftMessage/composer.json index a00f20427c706..5cc515e5922d9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GiftMessage/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GiftMessage/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAdwords/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAdwords/composer.json index cd3804122ec1f..8710e25cd469d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAdwords/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAdwords/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-sales": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAnalytics/composer.json index 3ac4ba7a20c08..63b7597a9d391 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-cookie": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleOptimizer/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleOptimizer/composer.json index 7bd4832051827..71d48969544e3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleOptimizer/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleOptimizer/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GraphQl/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GraphQl/composer.json index 05749f8295eba..701ed734f896c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GraphQl/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GraphQl/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-webapi": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedImportExport/composer.json index a5f2f1d4c9b3f..4460aef0ac60f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/composer.json index 4f4638a6e31cb..3ab2160e33de9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ImportExport/composer.json index c575fa78375de..4632adb4f904f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Indexer/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Indexer/composer.json index c8b81673fe810..35b8219186bd2 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Indexer/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Indexer/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/InstantPurchase/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/InstantPurchase/composer.json index b4e471fd62ed6..84c595020968c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/InstantPurchase/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/InstantPurchase/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-store": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Integration/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Integration/composer.json index 3fcda364a88cc..9f0ccb76c1cd3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Integration/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Integration/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/LayeredNavigation/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/LayeredNavigation/composer.json index dc2725e4a1d1e..447f3ba38a06c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/LayeredNavigation/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/LayeredNavigation/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Marketplace/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Marketplace/composer.json index 7f0909ff460a6..d4079dfefc9ba 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Marketplace/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Marketplace/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MediaStorage/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MediaStorage/composer.json index ef0cf6d0e7ec5..29657d03014bf 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MediaStorage/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MediaStorage/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Msrp/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Msrp/composer.json index 5d1d5b4e3f74a..b91aaddcba3f2 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Msrp/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Msrp/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Multishipping/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Multishipping/composer.json index cbc1fd9519105..ffd80908ed522 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Multishipping/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Multishipping/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/NewRelicReporting/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/NewRelicReporting/composer.json index 014a5773c9520..c6b60c43b6de0 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/NewRelicReporting/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/NewRelicReporting/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/composer.json index 131cc853f0438..eff14e85b04a0 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflinePayments/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflinePayments/composer.json index f4adf1b4a8603..f645c45abfdd0 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflinePayments/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflinePayments/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflineShipping/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflineShipping/composer.json index fb6bcd89a5c00..2fc319facc683 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflineShipping/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflineShipping/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/composer.json index c932ed0861247..2c4612b71a126 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Payment/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Payment/composer.json index 2f2b7fb8675e1..ea5f918171c8f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Payment/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Payment/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Paypal/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Paypal/composer.json index 9af738c291089..94c3af772673e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Paypal/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Paypal/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/composer.json index ec4f6754e5838..e12542a65d2be 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductAlert/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductAlert/composer.json index 93e3633101a8b..1dc3837e4b1fb 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductAlert/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductAlert/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductVideo/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductVideo/composer.json index c3766646ad050..0e1f83433049a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductVideo/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductVideo/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Quote/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Quote/composer.json index 4394d1f6ad3ad..7d3a16063745f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Quote/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Quote/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/QuoteAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/QuoteAnalytics/composer.json index 4bd28d1b3c903..0d249b0c40921 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/QuoteAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/QuoteAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-quote": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Reports/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Reports/composer.json index f76c29252118a..53d7e7b1c9c0e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Reports/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Reports/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/RequireJs/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/RequireJs/composer.json index b184fe40ce33b..2fcf3dc4c6103 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/RequireJs/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/RequireJs/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Review/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Review/composer.json index 10bcc87798b8c..4445be9e856cf 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Review/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Review/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ReviewAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ReviewAnalytics/composer.json index 546a20fe50c0f..d58c62a68dac5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ReviewAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ReviewAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-review": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Robots/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Robots/composer.json index 3b83ca8565b05..70cf4ba3203e4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Robots/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Robots/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-store": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rss/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rss/composer.json index 80ec362c2ce2e..9fa6d370cd610 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rss/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rss/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rule/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rule/composer.json index 30f200468e3f9..73dd74c5fa576 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rule/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rule/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/composer.json index 9c1805b3df12a..a6c8fbebe72fc 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesAnalytics/composer.json index 0b37233aa5927..3f96160f374d0 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-sales": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesInventory/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesInventory/composer.json index c4ab23c2d110e..6547bff428193 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesInventory/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesInventory/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/composer.json index f53960051cd8d..8d90ad55d988c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesSequence/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesSequence/composer.json index fb83f886ec02d..808f1394d6173 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesSequence/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesSequence/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleData/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleData/composer.json index 8b531192d0fe1..ed12f8bda3beb 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleData/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleData/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/composer.json index 81528e77bf827..e0ceb5bd23c1c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/composer.json index 7fdf84d34f99f..dc91e593e745b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Search/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Search/composer.json index 04b875efb6014..4dcc1a0620281 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Search/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Search/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Security/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Security/composer.json index 2ecb67d87d8ca..69f18fcfbc40f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Security/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Security/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SendFriend/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SendFriend/composer.json index 5f8bcdf51630f..0b7d03fa71fa7 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SendFriend/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SendFriend/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/composer.json index bbd403aa22894..fbe922ddc2d5c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/composer.json index 4ec67bdb7e675..6d1c9eb72dab4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/composer.json index 506e9cc06fdff..718efc04391ca 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/composer.json index ece658104cfe0..b9460ce939e86 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/composer.json index 1afb21a4e87bd..9632be9c9f172 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/composer.json index 330478b6e929d..0931a3c286d0a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json index 8c50d2d39a5f0..fb47e3fbeba58 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/composer.json index aff82b7a84e05..364981ffd1e95 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Theme/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Theme/composer.json index bc334e7ebc070..2c710540611bc 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Theme/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Theme/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/composer.json index c44f92a1dfcb9..3a0fb712810ad 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/composer.json index 905890a4cea9a..219f938fed196 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/composer.json index 06534e3b2b469..11aea7bbc68b7 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/composer.json index ab7e60435564d..d88d9a54264ee 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/composer.json index e4ab9263b5c9c..07c2ed3745de5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Usps/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Usps/composer.json index 4a6d5462d8016..5896bff636205 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Usps/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Usps/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/composer.json index 386ebdeedbf47..d70e75da77a03 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Vault/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Vault/composer.json index 9fa8fc8f6b6ec..88ce9046df10c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Vault/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Vault/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Version/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Version/composer.json index 69078adc39303..8a256bc40d42a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Version/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Version/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Webapi/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Webapi/composer.json index 7ddb760e9eb11..a00dbd244615f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Webapi/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Webapi/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WebapiSecurity/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WebapiSecurity/composer.json index 5ec58e1ff9e0f..3c26635fc3f6e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WebapiSecurity/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WebapiSecurity/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-webapi": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Weee/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Weee/composer.json index 019d957e96c54..b226f2b1697fa 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Weee/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Weee/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Widget/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Widget/composer.json index 94a03b6c64eeb..85c1d19bd696c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Widget/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Widget/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/composer.json index 660d4ce34c3be..8c5e0335f1b29 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WishlistAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WishlistAnalytics/composer.json index b49a321f44884..1f25efea7f90f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WishlistAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WishlistAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-wishlist": "100.0.0-dev" diff --git a/dev/tests/api-functional/_files/Magento/TestModuleIntegrationFromConfig/composer.json b/dev/tests/api-functional/_files/Magento/TestModuleIntegrationFromConfig/composer.json index 25b8baaa73f78..41d36bbdeafdd 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleIntegrationFromConfig/composer.json +++ b/dev/tests/api-functional/_files/Magento/TestModuleIntegrationFromConfig/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "0.42.0-beta8", "magento/module-integration": "0.42.0-beta8" }, diff --git a/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/composer.json b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/composer.json index ee6b92cca8403..d4b6349b53b08 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/composer.json +++ b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "0.42.0-beta8", "magento/module-sales": "0.42.0-beta8" }, diff --git a/dev/tests/functional/composer.json b/dev/tests/functional/composer.json index 0c9f329f234a8..a43a3390daa9a 100644 --- a/dev/tests/functional/composer.json +++ b/dev/tests/functional/composer.json @@ -3,7 +3,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/mtf": "1.0.0-rc59", "allure-framework/allure-phpunit": "~1.2.0", "doctrine/annotations": "1.4.*", diff --git a/dev/tests/integration/_files/Magento/TestModuleSample/composer.json b/dev/tests/integration/_files/Magento/TestModuleSample/composer.json index 6af2d2f46f50b..8df541bf6a008 100644 --- a/dev/tests/integration/_files/Magento/TestModuleSample/composer.json +++ b/dev/tests/integration/_files/Magento/TestModuleSample/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.1.*", "magento/module-integration": "100.1.*" }, diff --git a/dev/tests/integration/testsuite/Magento/Deploy/_files/zoom1/composer.json b/dev/tests/integration/testsuite/Magento/Deploy/_files/zoom1/composer.json index d0da19718eb33..b9be0b2fe61e8 100644 --- a/dev/tests/integration/testsuite/Magento/Deploy/_files/zoom1/composer.json +++ b/dev/tests/integration/testsuite/Magento/Deploy/_files/zoom1/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "~5.5.0|~5.6.0|~7.0.0|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "1.0.0-beta" }, "type": "magento2-theme", diff --git a/dev/tests/integration/testsuite/Magento/Deploy/_files/zoom2/composer.json b/dev/tests/integration/testsuite/Magento/Deploy/_files/zoom2/composer.json index 72bd3e4182d86..1070cec5742cc 100644 --- a/dev/tests/integration/testsuite/Magento/Deploy/_files/zoom2/composer.json +++ b/dev/tests/integration/testsuite/Magento/Deploy/_files/zoom2/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "~5.5.0|~5.6.0|~7.0.0|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "1.0.0-beta", "magento/theme-frontend-zoom1": "1.0.0-beta" }, diff --git a/dev/tests/integration/testsuite/Magento/Deploy/_files/zoom3/composer.json b/dev/tests/integration/testsuite/Magento/Deploy/_files/zoom3/composer.json index 1dbc757affb05..1ca56ebf06b5e 100644 --- a/dev/tests/integration/testsuite/Magento/Deploy/_files/zoom3/composer.json +++ b/dev/tests/integration/testsuite/Magento/Deploy/_files/zoom3/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "~5.5.0|~5.6.0|~7.0.0|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "1.0.0-beta", "magento/theme-frontend-zoom2": "1.0.0-beta" }, diff --git a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/A/composer.json b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/A/composer.json index 4e7a28a4bc5c2..c6836f980647d 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/A/composer.json +++ b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/A/composer.json @@ -4,7 +4,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "0.1", "magento/module-b": "0.1" }, diff --git a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/B/composer.json b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/B/composer.json index f8d4bd3f296bd..08e6d97a1af3b 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/B/composer.json +++ b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/B/composer.json @@ -4,7 +4,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "0.74.0-beta6", "magento/module-a": "0.1" }, diff --git a/dev/tests/integration/testsuite/Magento/Widget/_files/design/adminhtml/magento_basic/composer.json b/dev/tests/integration/testsuite/Magento/Widget/_files/design/adminhtml/magento_basic/composer.json index 4c41071f55925..d56e9ce4260a0 100644 --- a/dev/tests/integration/testsuite/Magento/Widget/_files/design/adminhtml/magento_basic/composer.json +++ b/dev/tests/integration/testsuite/Magento/Widget/_files/design/adminhtml/magento_basic/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "0.1.0-alpha103" }, "type": "magento2-theme", diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json index 785ff07a60f39..fc0bc33fbea45 100644 --- a/lib/internal/Magento/Framework/composer.json +++ b/lib/internal/Magento/Framework/composer.json @@ -11,7 +11,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "ext-curl": "*", "ext-dom": "*", "ext-gd": "*", From a64afce4719df4c4de3ae9d8b33998f3c995de5a Mon Sep 17 00:00:00 2001 From: Patrick McLain <pmclain@somethingdigital.com> Date: Wed, 28 Feb 2018 21:21:53 -0500 Subject: [PATCH 034/668] magento/framework composer.json updates Match library versions with those in project composer.json --- lib/internal/Magento/Framework/composer.json | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json index fc0bc33fbea45..4dd2d8a0402df 100644 --- a/lib/internal/Magento/Framework/composer.json +++ b/lib/internal/Magento/Framework/composer.json @@ -17,19 +17,18 @@ "ext-gd": "*", "ext-hash": "*", "ext-iconv": "*", - "ext-mcrypt": "*", "ext-openssl": "*", "ext-simplexml": "*", "ext-spl": "*", "ext-xsl": "*", "lib-libxml": "*", - "colinmollenhour/php-redis-session-abstract": "~1.2.2", - "composer/composer": "1.4.1", + "colinmollenhour/php-redis-session-abstract": "~1.3.8", + "composer/composer": "~1.6.0", "magento/zendframework1": "~1.13.0", "monolog/monolog": "^1.17", "oyejorge/less.php": "~1.7.0", - "symfony/console": "~2.3, !=2.7.0", - "symfony/process": "~2.1", + "symfony/console": "~4.0.0", + "symfony/process": "~4.0.0", "tedivm/jshrink": "~1.1.0", "zendframework/zend-code": "^3.1.0", "zendframework/zend-crypt": "^2.6.0", From 5708643b39b98e7482572fdbaf788b4ac5e192c3 Mon Sep 17 00:00:00 2001 From: Patrick McLain <pmclain@somethingdigital.com> Date: Wed, 28 Feb 2018 21:40:30 -0500 Subject: [PATCH 035/668] Replace php 7.0 with 7.2 in .travis.yml Fixes #25 --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index dcd00f39bb810..6be1ed84f3ff6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,8 +13,8 @@ addons: - magento2.travis language: php php: - - 7.0 - 7.1 + - 7.2 env: global: - COMPOSER_BIN_DIR=~/bin @@ -32,13 +32,13 @@ env: - TEST_SUITE=functional matrix: exclude: - - php: 7.0 + - php: 7.1 env: TEST_SUITE=static - - php: 7.0 + - php: 7.1 env: TEST_SUITE=js GRUNT_COMMAND=spec - - php: 7.0 + - php: 7.1 env: TEST_SUITE=js GRUNT_COMMAND=static - - php: 7.0 + - php: 7.1 env: TEST_SUITE=functional cache: apt: true From 5422e60c9f608f74a0ddf762dcb4ff717023fc8f Mon Sep 17 00:00:00 2001 From: Andrii Kasian <akasian@magento.com> Date: Thu, 1 Mar 2018 15:07:00 +0200 Subject: [PATCH 036/668] MAGETWO-88028: Table is full errors on same modify profile --- .../Product/Indexer/Price/IndexTableRowSizeEstimator.php | 2 +- .../Product/Indexer/Price/IndexTableRowSizeEstimatorTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/IndexTableRowSizeEstimator.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/IndexTableRowSizeEstimator.php index 89df6677f2490..7707fadffe98c 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/IndexTableRowSizeEstimator.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/IndexTableRowSizeEstimator.php @@ -15,7 +15,7 @@ class IndexTableRowSizeEstimator implements \Magento\Framework\Indexer\IndexTabl /** * Calculated memory size for one record in catalog_product_index_price table */ - const MEMORY_SIZE_FOR_ONE_ROW = 120; + const MEMORY_SIZE_FOR_ONE_ROW = 200; /** * @var \Magento\Store\Api\WebsiteManagementInterface diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/IndexTableRowSizeEstimatorTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/IndexTableRowSizeEstimatorTest.php index e5720b4f0536c..c0ecc4370816b 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/IndexTableRowSizeEstimatorTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/IndexTableRowSizeEstimatorTest.php @@ -38,7 +38,7 @@ protected function setUp() public function testEstimateRowSize() { - $expectedValue = 2400000; + $expectedValue = 4000000; $this->websiteManagementMock->expects($this->once())->method('getCount')->willReturn(100); $collectionMock = $this->createMock(\Magento\Customer\Model\ResourceModel\Group\Collection::class); From 1443516a92ab97b24f88283716934b48d738fb5e Mon Sep 17 00:00:00 2001 From: Alex Paliarush <apaliarush@magento.com> Date: Fri, 2 Mar 2018 18:32:46 -0600 Subject: [PATCH 037/668] [Prototype] GraphQL SDL to replace XML as configuration language Changes: - Disabled GraphQL XML config reader (config files and reader are still there) - Introduced GraphQL SDL config reader - Magento/GraphQl/etc/schema.graphql declares all entities currently declared in XML. It also includes fields generated by EAV config reader. Color field is removed from this schema to demonstrate that EAV config reader is still functional and its results are merged with the schema - Magento/CustomerGraphQl/etc/schema.graphql declares customer query, and adds test field to product interface to demonstrate extensibility and modularity - Introduced @resolver directive for fields and @typeResolver for interfaces. See usage examples in Magento/GraphQl/etc/schema.graphql Algorithm: - Reader collects 'etc/schema.graphql' files from all modules - Each schema is parsed using webonyx - All webonyx schema objects are converted into internal representation of GraphQL config and merged together. Internal representation is currently used by XML and EAV config readers - Resolvers are declared in SDL using custom directives - Finally, merged Webonyx schema object is generated from internal representation of GraphQL config. This behavior is not changed by the prototype Limitations: - Each individual schema.graphql must be valid prior merging Compatibility: - Quick smoke testing shows, that final GraphQL schema is not altered after refactoring - Product resolver works as before --- .../CustomerGraphQl/etc/schema.graphql | 53 + app/code/Magento/GraphQl/etc/di.xml | 4 +- app/code/Magento/GraphQl/etc/schema.graphql | 974 ++++++++++++++++++ .../GraphQl/Config/Common/Reader.php | 2 +- .../GraphQl/Config/GraphQlReader.php | 299 ++++++ 5 files changed, 1330 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/CustomerGraphQl/etc/schema.graphql create mode 100644 app/code/Magento/GraphQl/etc/schema.graphql create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php diff --git a/app/code/Magento/CustomerGraphQl/etc/schema.graphql b/app/code/Magento/CustomerGraphQl/etc/schema.graphql new file mode 100644 index 0000000000000..28a35683d2cea --- /dev/null +++ b/app/code/Magento/CustomerGraphQl/etc/schema.graphql @@ -0,0 +1,53 @@ +type Query { + customer: Customer @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\Customer") +} + +type Products { + testCustomizationFromCustomerConfig: String +} + +type Customer { + created_at: String + group_id: Int + prefix: String + firstname: String + middlename: String + lastname: String + suffix: String + email: String + default_billing: String + default_shipping: String + dob: String + taxvat: String + id: Int + is_subscribed: Boolean + addresses: [CustomerAddress] +} + +type CustomerAddress { + id: Int + customer_id: Int + region: CustomerAddressRegion + region_id: Int + country_id: String + street: [String] + company: String + telephone: String + fax: String + postcode: String + city: String + firstname: String + lastname: String + middlename: String + prefix: String + suffix: String + vat_id: String + default_shipping: Boolean + default_billing: Boolean +} + +type CustomerAddressRegion { + region_code: String + region: String + region_id: Int +} diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 5887cc958ff2e..f2717e5ae1bd5 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -47,7 +47,9 @@ <virtualType name="Magento\Framework\GraphQl\Config\Reader" type="Magento\Framework\GraphQl\Config\Common\Reader"> <arguments> <argument name="readers" xsi:type="array"> - <item name="xmlReader" xsi:type="object">Magento\Framework\GraphQl\Config\XmlReader</item> + <!--TODO: Delete all xml configs--> + <!--<item name="xmlReader" xsi:type="object">Magento\Framework\GraphQl\Config\XmlReader</item>--> + <item name="graphQlReader" xsi:type="object">Magento\Framework\GraphQl\Config\GraphQlReader</item> </argument> </arguments> </virtualType> diff --git a/app/code/Magento/GraphQl/etc/schema.graphql b/app/code/Magento/GraphQl/etc/schema.graphql new file mode 100644 index 0000000000000..5a492fbbbeb5a --- /dev/null +++ b/app/code/Magento/GraphQl/etc/schema.graphql @@ -0,0 +1,974 @@ +type Attribute { + attribute_code: String + entity_type: String + attribute_type: String +} + +input AttributeInput { + attribute_code: String + entity_type: String +} + +type BundleItem { + option_id: Int + title: String + required: Boolean + type: String + position: Int + sku: String + options: [BundleItemOption] +} + +type BundleItemOption { + id: Int + label: String + qty: Float + position: Int + is_default: Boolean + price: Float + price_type: PriceTypeEnum + can_change_quantity: Boolean + product: ProductInterface +} + +type BundleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface { + price_view: PriceViewEnum + dynamic_price: Boolean + dynamic_sku: Boolean + ship_bundle_items: ShipBundleItemsEnum + dynamic_weight: Boolean + items: [BundleItem] + url_key: String + url_path: String + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + swatch_image: String + tax_class_id: Int + weight: Float + options: [CustomizableOptionInterface] + color: Int + manufacturer: Int +} + +type ConfigurableProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface { + configurable_product_links: [SimpleProduct] + configurable_product_options: [ConfigurableProductOptions] + url_key: String + url_path: String + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + swatch_image: String + tax_class_id: Int + weight: Float + options: [CustomizableOptionInterface] + color: Int + manufacturer: Int +} + +type ConfigurableProductOptions { + id: Int + attribute_id: String + attribute_code: String + label: String + position: Int + is_use_default: Boolean + values: [ConfigurableProductOptionsValues] + product_id: Int +} + +type ConfigurableProductOptionsValues { + value_index: Int +} + +enum CurrencyEnum { + AFN + ALL + AZN + DZD + AOA + ARS + AMD + AWG + AUD + BSD + BHD + BDT + BBD + BYR + BZD + BMD + BTN + BOB + BAM + BWP + BRL + GBP + BND + BGN + BUK + BIF + KHR + CAD + CVE + CZK + KYD + GQE + CLP + CNY + COP + KMF + CDF + CRC + HRK + CUP + DKK + DJF + DOP + XCD + EGP + SVC + ERN + EEK + ETB + EUR + FKP + FJD + GMD + GEK + GEL + GHS + GIP + GTQ + GNF + GYD + HTG + HNL + HKD + HUF + ISK + INR + IDR + IRR + IQD + ILS + JMD + JPY + JOD + KZT + KES + KWD + KGS + LAK + LVL + LBP + LSL + LRD + LYD + LTL + MOP + MKD + MGA + MWK + MYR + MVR + LSM + MRO + MUR + MXN + MDL + MNT + MAD + MZN + MMK + NAD + NPR + ANG + YTL + NZD + NIC + NGN + KPW + NOK + OMR + PKR + PAB + PGK + PYG + PEN + PHP + PLN + QAR + RHD + RON + RUB + RWF + SHP + STD + SAR + RSD + SCR + SLL + SGD + SKK + SBD + SOS + ZAR + KRW + LKR + SDG + SRD + SZL + SEK + CHF + SYP + TWD + TJS + TZS + THB + TOP + TTD + TND + TMM + USD + UGX + UAH + AED + UYU + UZS + VUV + VEB + VEF + VND + CHE + CHW + XOF + WST + YER + ZMK + ZWD + TRY + AZM + ROL + TRL + XPF +} + +type CustomAttributeMetadata { + items: [Attribute] +} + +type CustomizableAreaOption implements CustomizableOptionInterface { + value: CustomizableAreaValue + product_sku: String + title: String + required: Boolean + sort_order: Int +} + +type CustomizableAreaValue { + price: Float + price_type: PriceTypeEnum + sku: String + max_characters: Int +} + +type CustomizableDateOption implements CustomizableOptionInterface { + value: CustomizableDateValue + product_sku: String + title: String + required: Boolean + sort_order: Int +} + +type CustomizableDateValue { + price: Float + price_type: PriceTypeEnum + sku: String +} + +type CustomizableDropDownOption implements CustomizableOptionInterface { + value: [CustomizableDropDownValue] + title: String + required: Boolean + sort_order: Int +} + +type CustomizableDropDownValue { + option_type_id: Int + price: Float + price_type: PriceTypeEnum + sku: String + title: String + sort_order: Int +} + +type CustomizableFieldOption implements CustomizableOptionInterface { + value: CustomizableFieldValue + product_sku: String + title: String + required: Boolean + sort_order: Int +} + +type CustomizableFieldValue { + price: Float + price_type: PriceTypeEnum + sku: String + max_characters: Int +} + +type CustomizableFileOption implements CustomizableOptionInterface { + value: CustomizableFileValue + product_sku: String + title: String + required: Boolean + sort_order: Int +} + +type CustomizableFileValue { + price: Float + price_type: PriceTypeEnum + sku: String + file_extension: String + image_size_x: Int + image_size_y: Int +} + +interface CustomizableOptionInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CustomizableOptionTypeResolver") { + title: String + required: Boolean + sort_order: Int +} + +interface CustomizableProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") { + options: [CustomizableOptionInterface] +} + +type CustomizableRadioOption implements CustomizableOptionInterface { + value: [CustomizableRadioValue] + title: String + required: Boolean + sort_order: Int +} + +type CustomizableRadioValue { + option_type_id: Int + price: Float + price_type: PriceTypeEnum + sku: String + title: String + sort_order: Int +} + +enum DownloadableFileTypeEnum { + FILE + URL +} + +type DownloadableProduct implements ProductInterface, CustomizableProductInterface { + downloadable_product_samples: [DownloadableProductSamples] + downloadable_product_links: [DownloadableProductLinks] + links_purchased_separately: Int + links_title: String + url_key: String + url_path: String + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + swatch_image: String + tax_class_id: Int + options: [CustomizableOptionInterface] + color: Int + manufacturer: Int +} + +type DownloadableProductLinks { + id: Int + title: String + sort_order: Int + is_shareable: Boolean + price: Float + number_of_downloads: Int + link_type: DownloadableFileTypeEnum + sample_type: DownloadableFileTypeEnum + sample_file: String + sample_url: String +} + +type DownloadableProductSamples { + id: Int + title: String + sort_order: Int + sample_type: DownloadableFileTypeEnum + sample_file: String + sample_url: String +} + +type EntityUrl { + id: Int + canonical_url: String + type: UrlRewriteEntityTypeEnum +} + +input FilterTypeInput { + eq: String + finset: [String] + from: String + gt: String + gteq: String + in: [String] + like: String + lt: String + lteq: String + moreq: String + neq: String + notnull: String + null: String + to: String + nin: [String] +} + +type GroupedProduct implements ProductInterface, PhysicalProductInterface { + items: [GroupedProductItem] + url_key: String + url_path: String + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + swatch_image: String + tax_class_id: Int + weight: Float + color: Int + manufacturer: Int +} + +type GroupedProductItem { + qty: Float + position: Int + product: ProductInterface +} + +type MediaGalleryEntry { + id: Int + media_type: String + label: String + position: Int + disabled: Boolean + types: [String] + file: String + content: ProductMediaGalleryEntriesContent + video_content: ProductMediaGalleryEntriesVideoContent +} + +type Money { + value: Float + currency: CurrencyEnum +} + +interface PhysicalProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") { + weight: Float +} + +type Price { + amount: Money + adjustments: [PriceAdjustment] +} + +type PriceAdjustment { + amount: Money + code: PriceAdjustmentCodesEnum + description: PriceAdjustmentDescriptionEnum +} + +enum PriceAdjustmentCodesEnum { + TAX + WEE + WEETAX +} + +enum PriceAdjustmentDescriptionEnum { + INCLUDED + EXCLUDED +} + +enum PriceTypeEnum { + FIXED + PERCENT + DYNAMIC +} + +enum PriceViewEnum { + PRICE_RANGE + AS_LOW_AS +} + +type ProductCategoryLinks { + position: Int + category_id: String +} + +input ProductFilterInput { + url_key: FilterTypeInput + url_path: FilterTypeInput + name: FilterTypeInput + sku: FilterTypeInput + description: FilterTypeInput + short_description: FilterTypeInput + price: FilterTypeInput + special_price: FilterTypeInput + special_from_date: FilterTypeInput + special_to_date: FilterTypeInput + weight: FilterTypeInput + manufacturer: FilterTypeInput + meta_title: FilterTypeInput + meta_keyword: FilterTypeInput + meta_description: FilterTypeInput + image: FilterTypeInput + small_image: FilterTypeInput + thumbnail: FilterTypeInput + tier_price: FilterTypeInput + color: FilterTypeInput + news_from_date: FilterTypeInput + news_to_date: FilterTypeInput + custom_design: FilterTypeInput + custom_design_from: FilterTypeInput + custom_design_to: FilterTypeInput + custom_layout_update: FilterTypeInput + page_layout: FilterTypeInput + category_ids: FilterTypeInput + options_container: FilterTypeInput + required_options: FilterTypeInput + has_options: FilterTypeInput + image_label: FilterTypeInput + small_image_label: FilterTypeInput + thumbnail_label: FilterTypeInput + created_at: FilterTypeInput + updated_at: FilterTypeInput + country_of_manufacture: FilterTypeInput + custom_layout: FilterTypeInput + gift_message_available: FilterTypeInput + or: ProductFilterInput + swatch_image: FilterTypeInput + tax_class_id: FilterTypeInput +} + +interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") { + url_key: String + url_path: String + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + swatch_image: String + tax_class_id: Int + manufacturer: Int +} + +type ProductLinks implements ProductLinksInterface { + sku: String + link_type: String + linked_product_sku: String + linked_product_type: String + position: Int +} + +interface ProductLinksInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductLinkTypeResolverComposite") { + sku: String + link_type: String + linked_product_sku: String + linked_product_type: String + position: Int +} + +type ProductMediaGalleryEntriesContent { + base64_encoded_data: String + type: String + name: String +} + +type ProductMediaGalleryEntriesVideoContent { + media_type: String + video_provider: String + video_url: String + video_title: String + video_description: String + video_metadata: String +} + +type ProductPrices { + minimalPrice: Price + maximalPrice: Price + regularPrice: Price +} + +input ProductSortInput { + url_key: SortEnum + url_path: SortEnum + name: SortEnum + sku: SortEnum + description: SortEnum + short_description: SortEnum + price: SortEnum + special_price: SortEnum + special_from_date: SortEnum + special_to_date: SortEnum + weight: SortEnum + manufacturer: SortEnum + meta_title: SortEnum + meta_keyword: SortEnum + meta_description: SortEnum + image: SortEnum + small_image: SortEnum + thumbnail: SortEnum + tier_price: SortEnum + color: SortEnum + news_from_date: SortEnum + news_to_date: SortEnum + custom_design: SortEnum + custom_design_from: SortEnum + custom_design_to: SortEnum + custom_layout_update: SortEnum + page_layout: SortEnum + category_ids: SortEnum + options_container: SortEnum + required_options: SortEnum + has_options: SortEnum + image_label: SortEnum + small_image_label: SortEnum + thumbnail_label: SortEnum + created_at: SortEnum + updated_at: SortEnum + country_of_manufacture: SortEnum + custom_layout: SortEnum + gift_message_available: SortEnum + swatch_image: SortEnum + tax_class_id: SortEnum +} + +type ProductTierPrices { + customer_group_id: String + qty: Float + value: Float + percentage_value: Float + website_id: Float +} + +type Products { + items: [ProductInterface] + page_info: SearchResultPageInfo + total_count: Int +} + +type Query { + products(search: String, filter: ProductFilterInput, pageSize: Int, currentPage: Int, sort: ProductSortInput): Products @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") + customAttributeMetadata(attributes: [AttributeInput!]!): CustomAttributeMetadata @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata") + urlResolver(url: String!): EntityUrl @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\UrlRewrite") +} + +type SearchResultPageInfo { + page_size: Int + current_page: Int +} + +enum ShipBundleItemsEnum { + TOGETHER + SEPARATELY +} + +type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface { + url_key: String + url_path: String + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + swatch_image: String + tax_class_id: Int + weight: Float + options: [CustomizableOptionInterface] + color: Int + manufacturer: Int +} + +enum SortEnum { + ASC + DESC +} + +enum UrlRewriteEntityTypeEnum { + PRODUCT + CATEGORY + CMS_PAGE +} + +type VirtualProduct implements ProductInterface, CustomizableProductInterface { + url_key: String + url_path: String + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + swatch_image: String + tax_class_id: Int + options: [CustomizableOptionInterface] + color: Int + manufacturer: Int +} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php b/lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php index c9c9217d1b579..911265b66c7e6 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php @@ -37,7 +37,7 @@ public function read($scope = null) { $output = []; foreach ($this->readers as $reader) { - $output = array_merge_recursive($output, $reader->read($scope)); + $output = array_replace_recursive($output, $reader->read($scope)); } return $output; } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php new file mode 100644 index 0000000000000..bcea215cfc0cf --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php @@ -0,0 +1,299 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Framework\GraphQl\Config; + +class GraphQlReader implements \Magento\Framework\Config\ReaderInterface +{ + /** + * File locator + * + * @var \Magento\Framework\Config\FileResolverInterface + */ + protected $fileResolver; + + /** + * @var string + */ + private $fileName; + + /** + * @var string + */ + protected $defaultScope; + + public function __construct( + \Magento\Framework\Config\FileResolverInterface $fileResolver, + $fileName = 'schema.graphql', + $defaultScope = 'global' + ) { + $this->fileResolver = $fileResolver; + $this->defaultScope = $defaultScope; + $this->fileName = $fileName; + } + + public function read($scope = null) + { + $result = []; + $scope = $scope ?: $this->defaultScope; + $schemaFiles = $this->fileResolver->get($this->fileName, $scope); + if (!count($schemaFiles)) { + return $result; + } + + foreach ($schemaFiles as $schemaContent) { + $partialResult = []; + $schema = \GraphQL\Utils\BuildSchema::build($schemaContent); + $typeMap = $schema->getTypeMap(); + foreach ($typeMap as $typeName => $typeMeta) { + if (strpos($typeName, '__') === 0) { + // Skip built-in object types + continue; + } + + if ($typeMeta instanceof \GraphQL\Type\Definition\ScalarType) { + // Skip built-in scalar types + continue; + } + + // TODO: Use polymorphism instead + if ($typeMeta instanceof \GraphQL\Type\Definition\EnumType) { + $partialResult[$typeName] = $this->readEnumTypeMeta($typeMeta); + continue; + } + if ($typeMeta instanceof \GraphQL\Type\Definition\ObjectType) { + $partialResult[$typeName] = $this->readObjectTypeMeta($typeMeta); + continue; + } + if ($typeMeta instanceof \GraphQL\Type\Definition\InputObjectType) { + $partialResult[$typeName] = $this->readInputObjectTypeMeta($typeMeta); + continue; + } + if ($typeMeta instanceof \GraphQL\Type\Definition\InterfaceType) { + $partialResult[$typeName] = $this->readInterfaceTypeMeta($typeMeta); + continue; + } + // TODO: This is necessary to catch unprocessed GraphQL types, like unions if the will be used in schema + throw new \LogicException("'{$typeName}' cannot be processed."); + } + $result = array_replace_recursive($result, $partialResult); + } + + return $result; + } + + + private function readEnumTypeMeta(\GraphQL\Type\Definition\EnumType $typeMeta) + { + $result = [ + 'name' => $typeMeta->name, + 'type' => 'graphql_enum', + 'items' => [] // Populated later + ]; + foreach ($typeMeta->getValues() as $value) { + // TODO: Simplify structure, currently name is lost during conversion to GraphQL schema + $result['items'][$value->value] = [ + 'name' => strtolower($value->name), + '_value' => $value->value + ]; + } + + return $result; + } + + private function isScalarType($type) + { + return in_array($type, ['String', 'Int', 'Float', 'Boolean', 'ID']); + } + + private function readObjectTypeMeta(\GraphQL\Type\Definition\ObjectType $typeMeta) + { + $typeName = $typeMeta->name; + $result = [ + 'name' => $typeName, + 'type' => 'graphql_type', + 'fields' => [], // Populated later + + ]; + + $interfaces = $typeMeta->getInterfaces(); + foreach ($interfaces as $interfaceMeta) { + $interfaceName = $interfaceMeta->name; + $result['implements'][$interfaceName] = [ + 'interface' => $interfaceName, + 'copyFields' => true // TODO: Configure in separate config + ]; + } + + $fields = $typeMeta->getFields(); + foreach ($fields as $fieldName => $fieldMeta) { + $result['fields'][$fieldName] = $this->readFieldMeta($fieldMeta); + } + + return $result; + } + + private function readInputObjectTypeMeta(\GraphQL\Type\Definition\InputObjectType $typeMeta) + { + $typeName = $typeMeta->name; + $result = [ + 'name' => $typeName, + 'type' => 'graphql_input', + 'fields' => [] // Populated later + ]; + $fields = $typeMeta->getFields(); + foreach ($fields as $fieldName => $fieldMeta) { + $result['fields'][$fieldName] = $this->readInputObjectFieldMeta($fieldMeta); + } + return $result; + } + + private function readInterfaceTypeMeta(\GraphQL\Type\Definition\InterfaceType $typeMeta) + { + $typeName = $typeMeta->name; + $result = [ + 'name' => $typeName, + 'type' => 'graphql_interface', + 'fields' => [] + ]; + + $interfaceTypeResolver = $this->readInterfaceTypeResolver($typeMeta); + if ($interfaceTypeResolver) { + $result['typeResolver'] = $interfaceTypeResolver; + } + + $fields = $typeMeta->getFields(); + foreach ($fields as $fieldName => $fieldMeta) { + $result['fields'][$fieldName] = $this->readFieldMeta($fieldMeta); + } + return $result; + } + + private function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) + { + $fieldName = $fieldMeta->name; + $fieldTypeMeta = $fieldMeta->getType(); + $result = [ + 'name' => $fieldName, + 'arguments' => [] + ]; + + $fieldResolver = $this->readFieldResolver($fieldMeta); + if ($fieldResolver) { + $result['resolver'] = $fieldResolver; + } + + $result = array_merge( + $result, + $this->readTypeMeta($fieldTypeMeta, 'OutputField') + ); + + $arguments = $fieldMeta->args; + foreach ($arguments as $argumentMeta) { + $argumentName = $argumentMeta->name; + $result['arguments'][$argumentName] = [ + 'name' => $argumentName, + ]; + $typeMeta = $argumentMeta->getType(); + $result['arguments'][$argumentName] = array_merge( + $result['arguments'][$argumentName], + $this->readTypeMeta($typeMeta, 'Argument') + ); + } + return $result; + } + + private function readInputObjectFieldMeta(\GraphQL\Type\Definition\InputObjectField $fieldMeta) + { + $fieldName = $fieldMeta->name; + $typeMeta = $fieldMeta->getType(); + $result = [ + 'name' => $fieldName, + 'required' => false, + // TODO arguments don't make sense here, but expected to be always present in \Magento\Framework\GraphQl\Config\Data\Mapper\TypeMapper::map + 'arguments' => [] + ]; + + $result = array_merge($result, $this->readTypeMeta($typeMeta, 'InputField')); + return $result; + } + + /** + * @param $meta + * @param string $parameterType Argument|OutputField|InputField + * @return mixed + */ + private function readTypeMeta($meta, $parameterType = 'Argument') + { + if ($meta instanceof \GraphQL\Type\Definition\NonNull) { + $result['required'] = true; + $meta = $meta->getWrappedType(); + } else { + $result['required'] = false; + } + if ($meta instanceof \GraphQL\Type\Definition\ListOfType) { + $itemTypeMeta = $meta->ofType; + if ($itemTypeMeta instanceof \GraphQL\Type\Definition\NonNull) { + $result['itemsRequired'] = true; + $itemTypeMeta = $itemTypeMeta->getWrappedType(); + } else { + $result['itemsRequired'] = false; + } + $result['description'] = $itemTypeMeta->description; + $itemTypeName = $itemTypeMeta->name; + $result['itemType'] = $itemTypeName; + if ($this->isScalarType($itemTypeMeta)) { + $result['type'] = 'ScalarArray' . $parameterType; + } else { + $result['type'] = 'ObjectArray' . $parameterType; + } + } else { + $result['description'] = $meta->description; + $result['type'] = $meta->name; + } + return $result; + } + + /** + * @param \GraphQL\Type\Definition\FieldDefinition $fieldMeta + * @return string|null + */ + private function readFieldResolver(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) + { + /** @var \GraphQL\Language\AST\NodeList $directives */ + $directives = $fieldMeta->astNode->directives; + foreach ($directives as $directive) { + if ($directive->name->value == 'resolver') { + foreach ($directive->arguments as $directiveArgument) { + if ($directiveArgument->name->value == 'class') { + return $directiveArgument->value->value; + } + } + } + } + return null; + } + + /** + * @param \GraphQL\Type\Definition\InterfaceType $interfaceTypeMeta + * @return string|null + */ + private function readInterfaceTypeResolver(\GraphQL\Type\Definition\InterfaceType $interfaceTypeMeta) + { + /** @var \GraphQL\Language\AST\NodeList $directives */ + $directives = $interfaceTypeMeta->astNode->directives; + foreach ($directives as $directive) { + if ($directive->name->value == 'typeResolver') { + foreach ($directive->arguments as $directiveArgument) { + if ($directiveArgument->name->value == 'class') { + return $directiveArgument->value->value; + } + } + } + } + return null; + } +} From 67ff564b5aea5b9d0eed2c965af559f6c3858698 Mon Sep 17 00:00:00 2001 From: Sergey <simpleadm@gmail.com> Date: Sat, 3 Mar 2018 08:28:16 +0300 Subject: [PATCH 038/668] Configurable product price options provider by store --- .../Price/LowestPriceOptionsProvider.php | 20 ++++++++++---- .../Price/LowestPriceOptionsProviderTest.php | 26 +++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionsProvider.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionsProvider.php index 66bc3db7ee89d..d3ce508b31e0d 100644 --- a/app/code/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionsProvider.php +++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionsProvider.php @@ -9,6 +9,7 @@ use Magento\Catalog\Model\ResourceModel\Product\LinkedProductSelectBuilderInterface; use Magento\Framework\App\ResourceConnection; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; +use Magento\Store\Model\StoreManagerInterface; /** * Retrieve list of products where each product contains lower price than others at least for one possible price type @@ -31,7 +32,12 @@ class LowestPriceOptionsProvider implements LowestPriceOptionsProviderInterface private $collectionFactory; /** - * Key is product id. Value is array of prepared linked products + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * Key is product id and store id. Value is array of prepared linked products * * @var array */ @@ -41,15 +47,18 @@ class LowestPriceOptionsProvider implements LowestPriceOptionsProviderInterface * @param ResourceConnection $resourceConnection * @param LinkedProductSelectBuilderInterface $linkedProductSelectBuilder * @param CollectionFactory $collectionFactory + * @param StoreManagerInterface $storeManager */ public function __construct( ResourceConnection $resourceConnection, LinkedProductSelectBuilderInterface $linkedProductSelectBuilder, - CollectionFactory $collectionFactory + CollectionFactory $collectionFactory, + StoreManagerInterface $storeManager ) { $this->resource = $resourceConnection; $this->linkedProductSelectBuilder = $linkedProductSelectBuilder; $this->collectionFactory = $collectionFactory; + $this->storeManager = $storeManager; } /** @@ -57,18 +66,19 @@ public function __construct( */ public function getProducts(ProductInterface $product) { - if (!isset($this->linkedProductMap[$product->getId()])) { + $key = $this->storeManager->getStore()->getId() . '-' . $product->getId(); + if (!isset($this->linkedProductMap[$key])) { $productIds = $this->resource->getConnection()->fetchCol( '(' . implode(') UNION (', $this->linkedProductSelectBuilder->build($product->getId())) . ')' ); - $this->linkedProductMap[$product->getId()] = $this->collectionFactory->create() + $this->linkedProductMap[$key] = $this->collectionFactory->create() ->addAttributeToSelect( ['price', 'special_price', 'special_from_date', 'special_to_date', 'tax_class_id'] ) ->addIdFilter($productIds) ->getItems(); } - return $this->linkedProductMap[$product->getId()]; + return $this->linkedProductMap[$key]; } } diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/LowestPriceOptionsProviderTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/LowestPriceOptionsProviderTest.php index ceeb242a750a2..7c83645a9fda3 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/LowestPriceOptionsProviderTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/LowestPriceOptionsProviderTest.php @@ -9,6 +9,9 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Model\ResourceModel\Product\LinkedProductSelectBuilderInterface; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Model\Store; class LowestPriceOptionsProviderTest extends \PHPUnit\Framework\TestCase { @@ -42,6 +45,16 @@ class LowestPriceOptionsProviderTest extends \PHPUnit\Framework\TestCase */ private $productCollection; + /** + * @var StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $storeManagerMock; + + /** + * @var StoreInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $storeMock; + protected function setUp() { $this->connection = $this @@ -68,6 +81,11 @@ protected function setUp() ->setMethods(['create']) ->getMock(); $this->collectionFactory->expects($this->once())->method('create')->willReturn($this->productCollection); + $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class) + ->getMockForAbstractClass(); + $this->storeMock = $this->getMockBuilder(StoreInterface::class) + ->setMethods(['getId']) + ->getMockForAbstractClass(); $objectManager = new ObjectManager($this); $this->model = $objectManager->getObject( @@ -76,6 +94,7 @@ protected function setUp() 'resourceConnection' => $this->resourceConnection, 'linkedProductSelectBuilder' => $this->linkedProductSelectBuilder, 'collectionFactory' => $this->collectionFactory, + 'storeManager' => $this->storeManagerMock, ] ); } @@ -94,6 +113,13 @@ public function testGetProducts() ->willReturnSelf(); $this->productCollection->expects($this->once())->method('addIdFilter')->willReturnSelf(); $this->productCollection->expects($this->once())->method('getItems')->willReturn($linkedProducts); + $this->storeManagerMock->expects($this->any()) + ->method('getStore') + ->with(Store::DEFAULT_STORE_ID) + ->willReturn($this->storeMock); + $this->storeMock->expects($this->any()) + ->method('getId') + ->willReturn(Store::DEFAULT_STORE_ID); $this->assertEquals($linkedProducts, $this->model->getProducts($product)); } From 24a7dab9a268955462fe7d048158f834f2353053 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <apaliarush@magento.com> Date: Tue, 6 Mar 2018 13:25:13 -0600 Subject: [PATCH 039/668] [Prototype] GraphQL SDL to replace XML as configuration language Changes: - Disabled GraphQL XML config reader (config files and reader are still there) - Introduced GraphQL SDL config reader - Magento/GraphQl/etc/schema.graphql declares all entities currently declared in XML. It also includes fields generated by EAV config reader. Color field is removed from this schema to demonstrate that EAV config reader is still functional and its results are merged with the schema - Magento/CustomerGraphQl/etc/schema.graphql declares customer query, and adds test field to product interface to demonstrate extensibility and modularity - Introduced @resolver directive for fields and @typeResolver for interfaces. See usage examples in Magento/GraphQl/etc/schema.graphql Algorithm changes: - Reader collects 'etc/schema.graphql' files from all modules - Split every schema into chunks representing declaration of a single type/interface/enum/union/input - Add all missing types from previously parsed schemas to the schema which is being processed. This step is required to prevent exceptions because of references to undeclared types - Each schema is parsed using webonyx - All webonyx schema objects are converted into internal representation of GraphQL config and merged together. Internal representation is currently used by XML and EAV config readers - Resolvers are declared in SDL using custom directives - Finally, merged Webonyx schema object is generated from internal representation of GraphQL config. This behavior is not changed by the prototype Compatibility: - All functional tests for products, customers and metadata are passing. The only failing tests are for test module and failing because GraphQL XML config declared in this module is now ignored. --- .../CustomerGraphQl/etc/schema.graphql | 5 --- app/code/Magento/GraphQl/etc/schema.graphql | 14 ++++---- .../GraphQl/Config/GraphQlReader.php | 35 ++++++++++++++++++- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/CustomerGraphQl/etc/schema.graphql b/app/code/Magento/CustomerGraphQl/etc/schema.graphql index 28a35683d2cea..46840b9f3e6af 100644 --- a/app/code/Magento/CustomerGraphQl/etc/schema.graphql +++ b/app/code/Magento/CustomerGraphQl/etc/schema.graphql @@ -46,8 +46,3 @@ type CustomerAddress { default_billing: Boolean } -type CustomerAddressRegion { - region_code: String - region: String - region_id: Int -} diff --git a/app/code/Magento/GraphQl/etc/schema.graphql b/app/code/Magento/GraphQl/etc/schema.graphql index 5a492fbbbeb5a..db58109d85ded 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphql +++ b/app/code/Magento/GraphQl/etc/schema.graphql @@ -1,3 +1,9 @@ +type CustomerAddressRegion { + region_code: String + region: String + region_id: Int +} + type Attribute { attribute_code: String entity_type: String @@ -84,7 +90,6 @@ type BundleProduct implements ProductInterface, PhysicalProductInterface, Custom tax_class_id: Int weight: Float options: [CustomizableOptionInterface] - color: Int manufacturer: Int } @@ -137,7 +142,6 @@ type ConfigurableProduct implements ProductInterface, PhysicalProductInterface, tax_class_id: Int weight: Float options: [CustomizableOptionInterface] - color: Int manufacturer: Int } @@ -491,7 +495,6 @@ type DownloadableProduct implements ProductInterface, CustomizableProductInterfa swatch_image: String tax_class_id: Int options: [CustomizableOptionInterface] - color: Int manufacturer: Int } @@ -588,7 +591,6 @@ type GroupedProduct implements ProductInterface, PhysicalProductInterface { swatch_image: String tax_class_id: Int weight: Float - color: Int manufacturer: Int } @@ -677,7 +679,6 @@ input ProductFilterInput { small_image: FilterTypeInput thumbnail: FilterTypeInput tier_price: FilterTypeInput - color: FilterTypeInput news_from_date: FilterTypeInput news_to_date: FilterTypeInput custom_design: FilterTypeInput @@ -807,7 +808,6 @@ input ProductSortInput { small_image: SortEnum thumbnail: SortEnum tier_price: SortEnum - color: SortEnum news_from_date: SortEnum news_to_date: SortEnum custom_design: SortEnum @@ -908,7 +908,6 @@ type SimpleProduct implements ProductInterface, PhysicalProductInterface, Custom tax_class_id: Int weight: Float options: [CustomizableOptionInterface] - color: Int manufacturer: Int } @@ -969,6 +968,5 @@ type VirtualProduct implements ProductInterface, CustomizableProductInterface { swatch_image: String tax_class_id: Int options: [CustomizableOptionInterface] - color: Int manufacturer: Int } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php index bcea215cfc0cf..cff510244ab65 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php @@ -44,7 +44,17 @@ public function read($scope = null) return $result; } - foreach ($schemaFiles as $schemaContent) { + /** + * Compatible with @see \Magento\Framework\GraphQl\Config\GraphQlReader::parseTypes + */ + $knownTypes = []; + foreach ($schemaFiles as $partialSchemaContent) { + $partialSchemaTypes = $this->parseTypes($partialSchemaContent); + /** + * Keep declarations from current partial schema, add missing declarations from all previously read schemas + */ + $knownTypes = $partialSchemaTypes + $knownTypes; + $schemaContent = implode("\n", $knownTypes); $partialResult = []; $schema = \GraphQL\Utils\BuildSchema::build($schemaContent); $typeMap = $schema->getTypeMap(); @@ -296,4 +306,27 @@ private function readInterfaceTypeResolver(\GraphQL\Type\Definition\InterfaceTyp } return null; } + + /** + * @param string $graphQlSchemaContent + * @return array [$typeName => $typeDeclaration, ...] + */ + private function parseTypes($graphQlSchemaContent) + { + $typeKindsPattern = '(type|interface|union|enum|input)'; + $typeNamePattern = '[_A-Za-z][_0-9A-Za-z]*'; + $typeDefinitionPattern = '.*\{[^\}]*\}'; + $spacePattern = '[\s\t\n\r]*'; + preg_match_all( + "/{$typeKindsPattern}{$spacePattern}({$typeNamePattern}){$spacePattern}{$typeDefinitionPattern}/i", + $graphQlSchemaContent, + $matches + ); + /** + * $matches[0] is an indexed array with the whole type definitions + * $matches[2] is an indexed array with type names + */ + $parsedTypes = array_combine($matches[2], $matches[0]); + return $parsedTypes; + } } From 8d107686213e4956d1db8b4a477d63fdc3454180 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <apaliarush@magento.com> Date: Tue, 6 Mar 2018 17:33:35 -0600 Subject: [PATCH 040/668] [Prototype] GraphQL SDL to replace XML as configuration language Changes: - Introduced GraphQL SDL config reader - Magento/GraphQl/etc/schema.graphql declares all entities currently declared in XML. It also includes fields generated by EAV config reader. Color field is removed from this schema to demonstrate that EAV config reader is still functional and its results are merged with the schema - Magento/CustomerGraphQl/etc/schema.graphql declares customer query, and adds test field to product interface to demonstrate extensibility and modularity - Introduced @resolver directive for fields and @typeResolver for interfaces. See usage examples in Magento/GraphQl/etc/schema.graphql - Disabled GraphQL XML config reader. Migrated all CE modules to schema.graphql configs, removed graphql.xml. EE is not refactored Algorithm: - Reader collects 'etc/schema.graphql' files from all modules - Split every schema into chunks representing declaration of a single type/interface/enum/union/input - Add all missing types from previously parsed schemas to the schema which is being processed. This step is required to prevent exceptions because of references to undeclared types - Each schema is parsed using webonyx - All webonyx schema objects are converted into internal representation of GraphQL config and merged together. Internal representation is currently used by XML and EAV config readers - Resolvers are declared in SDL using custom directives - Finally, merged Webonyx schema object is generated from internal representation of GraphQL config. This behavior is not changed by the prototype QA: - All CE functional tests for products, customers and metadata are passing. The only failing tests are for test module and failing because GraphQL XML config declared in this module is now ignored. Restrictions and open questions: - Fields copying from the interface to the type declaration is not supported. As a result the same fields must be declared in all product types. This affects extensibility, see Magento/SwatchesGraphQl/etc/schema.graphql as an example - 'Query' must be declared in Magento/GraphQl/etc/schema.graphql. For now fake field used there. Should be resolved - It is not possible anymore to declare empty types, which are extended by other modules. Affected types: PriceAdjustmentCodesEnum, UrlRewriteEntityTypeEnum --- .../Magento/BundleGraphQl/etc/graphql.xml | 49 - .../Magento/BundleGraphQl/etc/schema.graphql | 84 ++ .../Magento/CatalogGraphQl/etc/graphql.xml | 477 --------- .../Magento/CatalogGraphQl/etc/schema.graphql | 599 +++++++++++ .../CatalogUrlRewriteGraphQl/etc/graphql.xml | 23 - .../etc/schema.graphql | 46 + .../CmsUrlRewriteGraphQl/etc/graphql.xml | 10 - .../CmsUrlRewriteGraphQl/etc/schema.graphql | 3 + .../etc/graphql.xml | 27 - .../etc/schema.graphql | 62 ++ .../Magento/CustomerGraphQl/etc/graphql.xml | 54 - .../CustomerGraphQl/etc/schema.graphql | 10 +- .../DownloadableGraphQl/etc/graphql.xml | 39 - .../DownloadableGraphQl/etc/schema.graphql | 75 ++ app/code/Magento/EavGraphQl/etc/graphql.xml | 24 - .../Magento/EavGraphQl/etc/schema.graphql | 18 + app/code/Magento/GraphQl/etc/graphql.xml | 33 - app/code/Magento/GraphQl/etc/schema.graphql | 945 +----------------- .../GroupedProductGraphQl/etc/graphql.xml | 17 - .../GroupedProductGraphQl/etc/schema.graphql | 51 + .../Magento/SwatchesGraphQl/etc/graphql.xml | 16 - .../SwatchesGraphQl/etc/schema.graphql | 35 + app/code/Magento/TaxGraphQl/etc/graphql.xml | 19 - .../Magento/TaxGraphQl/etc/schema.graphql | 35 + .../Magento/UrlRewriteGraphQl/etc/graphql.xml | 18 - .../UrlRewriteGraphQl/etc/schema.graphql | 14 + app/code/Magento/WeeeGraphQl/etc/graphql.xml | 11 - .../Magento/WeeeGraphQl/etc/schema.graphql | 4 + 28 files changed, 1034 insertions(+), 1764 deletions(-) delete mode 100644 app/code/Magento/BundleGraphQl/etc/graphql.xml create mode 100644 app/code/Magento/BundleGraphQl/etc/schema.graphql delete mode 100644 app/code/Magento/CatalogGraphQl/etc/graphql.xml create mode 100644 app/code/Magento/CatalogGraphQl/etc/schema.graphql delete mode 100644 app/code/Magento/CatalogUrlRewriteGraphQl/etc/graphql.xml create mode 100644 app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql delete mode 100644 app/code/Magento/CmsUrlRewriteGraphQl/etc/graphql.xml create mode 100644 app/code/Magento/CmsUrlRewriteGraphQl/etc/schema.graphql delete mode 100644 app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml create mode 100644 app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql delete mode 100644 app/code/Magento/CustomerGraphQl/etc/graphql.xml delete mode 100644 app/code/Magento/DownloadableGraphQl/etc/graphql.xml create mode 100644 app/code/Magento/DownloadableGraphQl/etc/schema.graphql delete mode 100644 app/code/Magento/EavGraphQl/etc/graphql.xml create mode 100644 app/code/Magento/EavGraphQl/etc/schema.graphql delete mode 100644 app/code/Magento/GraphQl/etc/graphql.xml delete mode 100644 app/code/Magento/GroupedProductGraphQl/etc/graphql.xml create mode 100644 app/code/Magento/GroupedProductGraphQl/etc/schema.graphql delete mode 100644 app/code/Magento/SwatchesGraphQl/etc/graphql.xml create mode 100644 app/code/Magento/SwatchesGraphQl/etc/schema.graphql delete mode 100644 app/code/Magento/TaxGraphQl/etc/graphql.xml create mode 100644 app/code/Magento/TaxGraphQl/etc/schema.graphql delete mode 100644 app/code/Magento/UrlRewriteGraphQl/etc/graphql.xml create mode 100644 app/code/Magento/UrlRewriteGraphQl/etc/schema.graphql delete mode 100644 app/code/Magento/WeeeGraphQl/etc/graphql.xml create mode 100644 app/code/Magento/WeeeGraphQl/etc/schema.graphql diff --git a/app/code/Magento/BundleGraphQl/etc/graphql.xml b/app/code/Magento/BundleGraphQl/etc/graphql.xml deleted file mode 100644 index 531bec37ba8e7..0000000000000 --- a/app/code/Magento/BundleGraphQl/etc/graphql.xml +++ /dev/null @@ -1,49 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> - <type xsi:type="OutputType" name="BundleProduct"> - <implements interface="ProductInterface" copyFields="true"/> - <implements interface="PhysicalProductInterface" copyFields="true"/> - <implements interface="CustomizableProductInterface" copyFields="true"/> - <field xsi:type="ObjectOutputField" name="price_view" type="PriceViewEnum" description="One of PRICE_RANGE or AS_LOW_AS"/> - <field xsi:type="ScalarOutputField" name="dynamic_price" type="Boolean" description="Indicates whether the bundle product has a dynamic price."/> - <field xsi:type="ScalarOutputField" name="dynamic_sku" type="Boolean" description="Indicates whether the bundle product has a dynamic SKU."/> - <field xsi:type="ObjectOutputField" name="ship_bundle_items" type="ShipBundleItemsEnum" description="Indicates whether to ship bundle items together or individually."/> - <field xsi:type="ScalarOutputField" name="dynamic_weight" type="Boolean" description="Indicates whether the bundle product has a dynamically calculated weight."/> - <field xsi:type="ObjectArrayOutputField" name="items" itemType="BundleItem" description="An array containing information about individual bundle items."/> - </type> - <type xsi:type="OutputType" name="BundleItem"> - <field xsi:type="ScalarOutputField" name="option_id" type="Int" description="An ID assigned to each type of item in a bundle product."/> - <field xsi:type="ScalarOutputField" name="title" type="String" description="The display name of the item"/> - <field xsi:type="ScalarOutputField" name="required" type="Boolean" description="Indicates whether the item must be included in the bundle."/> - <field xsi:type="ScalarOutputField" name="type" type="String" description="The input type that the customer uses to select the item. Examples include radio button and checkbox." /> - <field xsi:type="ScalarOutputField" name="position" type="Int" description="The relative position of this item compared to the other bundle items."/> - <field xsi:type="ScalarOutputField" name="sku" type="String" description="The SKU of the bundle product"/> - <field xsi:type="ObjectArrayOutputField" name="options" itemType="BundleItemOption" description="An array of additional options for this bundle item"/> - </type> - <type xsi:type="OutputType" name="BundleItemOption"> - <!-- is product_id same with entity_id and id ?? --> - <field xsi:type="ScalarOutputField" name="id" type="Int" description="The ID assigned to the bundled item option"/> - <field xsi:type="ScalarOutputField" name="label" type="String" description="The text that identifies the bundled item option"/> - <!--<field xsi:type="ScalarOutputField" name="option_id" type="Int"/>--> - <field xsi:type="ScalarOutputField" name="qty" type="Float" description="Indicates the quantity of this specific bundle item"/> - <field xsi:type="ScalarOutputField" name="position" type="Int" description="When a bundle item contains multiple options, the relative position of this option compared to the other options"/> - <field xsi:type="ScalarOutputField" name="is_default" type="Boolean" description="Indicates whether this option is the default option"/> - <!-- price type and price don't get populated is it something about fixed price ? --> - <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price of the selected option"/> - <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="One of FIXED, PERCENT, or DYNAMIC"/> - <field xsi:type="ScalarOutputField" name="can_change_quantity" type="Boolean" description="Indicates whether the customer can change the number of items for this option"/> - <field xsi:type="ObjectOutputField" name="product" type="ProductInterface" description="The ProductInterface object, which contains details about this product option"/> - </type> - <type xsi:type="Enum" name="ShipBundleItemsEnum"> - <item name="together">TOGETHER</item> - <item name="separately">SEPARATELY</item> - </type> - <type xsi:type="Enum" name="PriceViewEnum"> - <item name="price_range">PRICE_RANGE</item> - <item name="as_low_as">AS_LOW_AS</item> - </type> -</config> diff --git a/app/code/Magento/BundleGraphQl/etc/schema.graphql b/app/code/Magento/BundleGraphQl/etc/schema.graphql new file mode 100644 index 0000000000000..29a0851ab8a75 --- /dev/null +++ b/app/code/Magento/BundleGraphQl/etc/schema.graphql @@ -0,0 +1,84 @@ + +type BundleItem { + option_id: Int + title: String + required: Boolean + type: String + position: Int + sku: String + options: [BundleItemOption] +} + +type BundleItemOption { + id: Int + label: String + qty: Float + position: Int + is_default: Boolean + price: Float + price_type: PriceTypeEnum + can_change_quantity: Boolean + product: ProductInterface +} + +type BundleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface { + price_view: PriceViewEnum + dynamic_price: Boolean + dynamic_sku: Boolean + ship_bundle_items: ShipBundleItemsEnum + dynamic_weight: Boolean + items: [BundleItem] + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + weight: Float + options: [CustomizableOptionInterface] + manufacturer: Int +} + +enum PriceViewEnum { + PRICE_RANGE + AS_LOW_AS +} + +enum ShipBundleItemsEnum { + TOGETHER + SEPARATELY +} diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql.xml b/app/code/Magento/CatalogGraphQl/etc/graphql.xml deleted file mode 100644 index 6e5abe697a101..0000000000000 --- a/app/code/Magento/CatalogGraphQl/etc/graphql.xml +++ /dev/null @@ -1,477 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> - <type xsi:type="OutputType" name="Query"> - <field xsi:type="ObjectOutputField" name="products" type="Products" resolver="Magento\CatalogGraphQl\Model\Resolver\Products"> - <argument xsi:type="ScalarArgument" name="search" type="String" description="Text to be used in a full text search. If multiple keywords are specified, each keyword is evaluated separately."/> - <argument xsi:type="ObjectArgument" name="filter" type="ProductFilterInput" description="Defines which search criteria to use to find the desired results. Each filter defines the field or fields to be searched, the condition type, and the search value."/> - <argument xsi:type="ScalarArgument" name="pageSize" type="Int" description="The maximum number of items to return. If no value is specified, the search returns 20 items."/> - <argument xsi:type="ScalarArgument" name="currentPage" type="Int" description="Specifies which page of results to return. If no value is specified, the first page is returned. If you specify a value that is greater than the number of available pages, an error is returned."/> - <argument xsi:type="ObjectArgument" name="sort" type="ProductSortInput" description="Specifies which field or fields to use for sorting the results. If you specify more than one field, Magento sorts by the first field listed. Then, if any items have the same value, those items will be sorted by the secondary field. The value for each field can be set to either ASC (ascending) or DESC (descending)."/> - </field> - </type> - <type xsi:type="Enum" name="CurrencyEnum"> - <item name="afn">AFN</item> - <item name="all">ALL</item> - <item name="azn">AZN</item> - <item name="dzd">DZD</item> - <item name="aoa">AOA</item> - <item name="ars">ARS</item> - <item name="amd">AMD</item> - <item name="awg">AWG</item> - <item name="aud">AUD</item> - <item name="bsd">BSD</item> - <item name="bhd">BHD</item> - <item name="bdt">BDT</item> - <item name="bbd">BBD</item> - <item name="byr">BYR</item> - <item name="bzd">BZD</item> - <item name="bmd">BMD</item> - <item name="btn">BTN</item> - <item name="bob">BOB</item> - <item name="bam">BAM</item> - <item name="bwp">BWP</item> - <item name="brl">BRL</item> - <item name="gbp">GBP</item> - <item name="bnd">BND</item> - <item name="bgn">BGN</item> - <item name="buk">BUK</item> - <item name="bif">BIF</item> - <item name="khr">KHR</item> - <item name="cad">CAD</item> - <item name="cve">CVE</item> - <item name="czk">CZK</item> - <item name="kyd">KYD</item> - <item name="gqe">GQE</item> - <item name="clp">CLP</item> - <item name="cny">CNY</item> - <item name="cop">COP</item> - <item name="kmf">KMF</item> - <item name="cdf">CDF</item> - <item name="crc">CRC</item> - <item name="hrk">HRK</item> - <item name="cup">CUP</item> - <item name="dkk">DKK</item> - <item name="djf">DJF</item> - <item name="dop">DOP</item> - <item name="xcd">XCD</item> - <item name="egp">EGP</item> - <item name="svc">SVC</item> - <item name="ern">ERN</item> - <item name="eek">EEK</item> - <item name="etb">ETB</item> - <item name="eur">EUR</item> - <item name="fkp">FKP</item> - <item name="fjd">FJD</item> - <item name="gmd">GMD</item> - <item name="gek">GEK</item> - <item name="gel">GEL</item> - <item name="ghs">GHS</item> - <item name="gip">GIP</item> - <item name="gtq">GTQ</item> - <item name="gnf">GNF</item> - <item name="gyd">GYD</item> - <item name="htg">HTG</item> - <item name="hnl">HNL</item> - <item name="hkd">HKD</item> - <item name="huf">HUF</item> - <item name="isk">ISK</item> - <item name="inr">INR</item> - <item name="idr">IDR</item> - <item name="irr">IRR</item> - <item name="iqd">IQD</item> - <item name="ils">ILS</item> - <item name="jmd">JMD</item> - <item name="jpy">JPY</item> - <item name="jod">JOD</item> - <item name="kzt">KZT</item> - <item name="kes">KES</item> - <item name="kwd">KWD</item> - <item name="kgs">KGS</item> - <item name="lak">LAK</item> - <item name="lvl">LVL</item> - <item name="lbp">LBP</item> - <item name="lsl">LSL</item> - <item name="lrd">LRD</item> - <item name="lyd">LYD</item> - <item name="ltl">LTL</item> - <item name="mop">MOP</item> - <item name="mkd">MKD</item> - <item name="mga">MGA</item> - <item name="mwk">MWK</item> - <item name="myr">MYR</item> - <item name="mvr">MVR</item> - <item name="lsm">LSM</item> - <item name="mro">MRO</item> - <item name="mur">MUR</item> - <item name="mxn">MXN</item> - <item name="mdl">MDL</item> - <item name="mnt">MNT</item> - <item name="mad">MAD</item> - <item name="mzn">MZN</item> - <item name="mmk">MMK</item> - <item name="nad">NAD</item> - <item name="npr">NPR</item> - <item name="ang">ANG</item> - <item name="ytl">YTL</item> - <item name="nzd">NZD</item> - <item name="nic">NIC</item> - <item name="ngn">NGN</item> - <item name="kpw">KPW</item> - <item name="nok">NOK</item> - <item name="omr">OMR</item> - <item name="pkr">PKR</item> - <item name="pab">PAB</item> - <item name="pgk">PGK</item> - <item name="pyg">PYG</item> - <item name="pen">PEN</item> - <item name="php">PHP</item> - <item name="pln">PLN</item> - <item name="qar">QAR</item> - <item name="rhd">RHD</item> - <item name="ron">RON</item> - <item name="rub">RUB</item> - <item name="rwf">RWF</item> - <item name="shp">SHP</item> - <item name="std">STD</item> - <item name="sar">SAR</item> - <item name="rsd">RSD</item> - <item name="scr">SCR</item> - <item name="sll">SLL</item> - <item name="sgd">SGD</item> - <item name="skk">SKK</item> - <item name="sbd">SBD</item> - <item name="sos">SOS</item> - <item name="zar">ZAR</item> - <item name="krw">KRW</item> - <item name="lkr">LKR</item> - <item name="sdg">SDG</item> - <item name="srd">SRD</item> - <item name="szl">SZL</item> - <item name="sek">SEK</item> - <item name="chf">CHF</item> - <item name="syp">SYP</item> - <item name="twd">TWD</item> - <item name="tjs">TJS</item> - <item name="tzs">TZS</item> - <item name="thb">THB</item> - <item name="top">TOP</item> - <item name="ttd">TTD</item> - <item name="tnd">TND</item> - <item name="tmm">TMM</item> - <item name="usd">USD</item> - <item name="ugx">UGX</item> - <item name="uah">UAH</item> - <item name="aed">AED</item> - <item name="uyu">UYU</item> - <item name="uzs">UZS</item> - <item name="vuv">VUV</item> - <item name="veb">VEB</item> - <item name="vef">VEF</item> - <item name="vnd">VND</item> - <item name="che">CHE</item> - <item name="chw">CHW</item> - <item name="xof">XOF</item> - <item name="wst">WST</item> - <item name="yer">YER</item> - <item name="zmk">ZMK</item> - <item name="zwd">ZWD</item> - <item name="try">TRY</item> - <item name="azm">AZM</item> - <item name="rol">ROL</item> - <item name="trl">TRL</item> - <item name="xpf">XPF</item> - </type> - <type xsi:type="Enum" name="PriceAdjustmentCodesEnum"/> - <type xsi:type="Enum" name="PriceAdjustmentDescriptionEnum"> - <item name="included">INCLUDED</item> - <item name="excluded">EXCLUDED</item> - </type> - <type xsi:type="OutputType" name="Money"> - <field xsi:type="ScalarOutputField" name="value" type="Float" description="A number expressing a monetary value."/> - <field xsi:type="ObjectOutputField" name="currency" type="CurrencyEnum" description="A three-letter currency code, such as `USD` or `EUR`."/> - </type> - <type xsi:type="OutputType" name="Price"> - <field xsi:type="ObjectOutputField" name="amount" type="Money" description="The price of a product plus a three-letter currency code."/> - <field xsi:type="ObjectArrayOutputField" name="adjustments" itemType="PriceAdjustment" description="An array that provides information about tax, weee, or weee_tax adjustments."/> - </type> - <type xsi:type="OutputType" name="PriceAdjustment"> - <field xsi:type="ObjectOutputField" name="amount" type="Money" description="The amount of the price adjustment and its currency code."/> - <field xsi:type="ObjectOutputField" name="code" type="PriceAdjustmentCodesEnum" description="Indicates whether the adjustment involves tax, weee, or weee_tax"/> - <field xsi:type="ObjectOutputField" name="description" type="PriceAdjustmentDescriptionEnum" description="Indicates whether the entity described by the code attribute is included or excluded from the adjustment."/> - </type> - <type xsi:type="OutputType" name="ProductPrices"> - <field xsi:type="ObjectOutputField" name="minimalPrice" type="Price" description="Used for composite (bundle, configurable, grouped) products. This is the lowest possible final price for all the options defined within a composite product. If you're specifying a price range, this would be the 'from' value."/> - <field xsi:type="ObjectOutputField" name="maximalPrice" type="Price" description="Used for composite (bundle, configurable, grouped) products. This is the highest possible final price for all the options defined within a composite product. If you're specifying a price range, this would be the 'to' value."/> - <field xsi:type="ObjectOutputField" name="regularPrice" type="Price" description="The base price of a product."/> - </type> - <type xsi:type="OutputType" name="ProductCategoryLinks"> - <field xsi:type="ScalarOutputField" name="position" type="Int" description="The position of the category in the category tree"/> - <field xsi:type="ScalarOutputField" name="category_id" type="String" description="The unique identifier for the category"/> - </type> - <type xsi:type="OutputInterface" name="ProductLinksInterface" typeResolver="Magento\CatalogGraphQl\Model\ProductLinkTypeResolverComposite"> - <field xsi:type="ScalarOutputField" name="sku" type="String" description="The identifier of the linked product"/> - <field xsi:type="ScalarOutputField" name="link_type" type="String" description="One of 'related', 'associated', 'upsell', or 'crosssell'."/> - <field xsi:type="ScalarOutputField" name="linked_product_sku" type="String" description="The SKU of the linked product"/> - <field xsi:type="ScalarOutputField" name="linked_product_type" type="String" description="The type of linked product ('simple', 'virtual', 'bundle', 'downloadable','grouped', 'configurable')"/> - <field xsi:type="ScalarOutputField" name="position" type="Int" description="The position within the list of product links"/> - </type> - <type xsi:type="OutputType" name="ProductLinks"> - <implements interface="ProductLinksInterface" copyFields="true"/> - </type> - <type xsi:type="OutputType" name="ProductTierPrices"> - <field xsi:type="ScalarOutputField" name="customer_group_id" type="Int" description="The ID of the customer group"/> - <field xsi:type="ScalarOutputField" name="qty" type="Float" description="The number of items that must be purchased to qualify for tier pricing."/> - <field xsi:type="ScalarOutputField" name="value" type="Float" description="The price of the fixed price item"/> - <field xsi:type="ScalarOutputField" name="percentage_value" type="Float" description="The percentage discount of the item"/> - <field xsi:type="ScalarOutputField" name="website_id" type="Float" description="The ID assigned to the website"/> - <field xsi:type="ScalarOutputField" name="customer_group_id" type="String" description="The ID of the customer group"/> - </type> - <type xsi:type="OutputInterface" name="ProductInterface" typeResolver="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> - <field xsi:type="ScalarOutputField" name="id" type="Int" description="The ID number assigned to the product."/> - <field xsi:type="ScalarOutputField" name="name" type="String" description="The product name. Customers use this name to identify the product."/> - <field xsi:type="ScalarOutputField" name="sku" type="String" description="A number or code assigned to a product to identify the product, options, price, and manufacturer."/> - <field xsi:type="ScalarOutputField" name="description" type="String" description="A detailed information about the product. The value can include simple HTML tags."/> - <field xsi:type="ScalarOutputField" name="short_description" type="String" description="A short description of the product. Its use depends on the theme."/> - <field xsi:type="ScalarOutputField" name="special_price" type="Float" description="The discounted price of the product"/> - <field xsi:type="ScalarOutputField" name="special_from_date" type="String" description="The beginning date that a product has a special price."/> - <field xsi:type="ScalarOutputField" name="special_to_date" type="String" description="The end date that a product has a special price."/> - <field xsi:type="ScalarOutputField" name="attribute_set_id" type="Int" description="The attribute set assigned to the product."/> - <field xsi:type="ScalarOutputField" name="meta_title" type="String" description="A string that is displayed in the title bar and tab of the browser and in search results lists."/> - <field xsi:type="ScalarOutputField" name="meta_keyword" type="String" description="A comma-separated list of keywords that are visible only to search engines."/> - <field xsi:type="ScalarOutputField" name="meta_description" type="String" description="A brief overview of the product for search results listings. Maximum 255 characters."/> - <field xsi:type="ScalarOutputField" name="image" type="String" description="The relative path for the main image on the product page."/> - <field xsi:type="ScalarOutputField" name="small_image" type="String" description="The file name of a small image, which is used on catalog pages."/> - <field xsi:type="ScalarOutputField" name="thumbnail" type="String" description="The file name of a thumbnail image"/> - <field xsi:type="ScalarOutputField" name="new_from_date" type="String" description="The beginning date for new product listings, and determines if the product is featured as a new product. Note: The input attribute name is 'news_from_date'."/> - <field xsi:type="ScalarOutputField" name="new_to_date" type="String" description="The end date for new product listings. Note: The input attribute name is 'news_to_date'."/> - <field xsi:type="ScalarOutputField" name="tier_price" type="Float" description="The price when tier pricing is in effect and the items purchased threshold has been reached."/> - <field xsi:type="ScalarOutputField" name="custom_design" type="String" description="A theme that can be applied to the product page."/> - <field xsi:type="ScalarOutputField" name="custom_design_from" type="String" description="The beginning date when a theme is applied to the product page."/> - <field xsi:type="ScalarOutputField" name="custom_design_to" type="String" description="The date at which a theme is no longer applied to the product page."/> - <field xsi:type="ScalarOutputField" name="custom_layout_update" type="String" description="XML code that is applied as a layout update to the product page."/> - <field xsi:type="ScalarOutputField" name="custom_layout" type="String" description="The name of a custom layout."/> - <field xsi:type="ScalarOutputField" name="page_layout" type="String" description="The page layout of the product page. Values include '1column-center', '2columns-left', '2columns-right', and '3columns'."/> - <field xsi:type="ScalarArrayOutputField" name="category_ids" itemType="Int" description="An array of category IDs the product belongs to."/> - <field xsi:type="ScalarOutputField" name="options_container" type="String" description="If the product has multiple options, determines where they appear on the product page."/> - <field xsi:type="ScalarOutputField" name="image_label" type="String" description="The label assigned to a product image."/> - <field xsi:type="ScalarOutputField" name="small_image_label" type="String" description="The label assigned to a product's small image."/> - <field xsi:type="ScalarOutputField" name="thumbnail_label" type="String" description="The label assigned to a product's thumbnail image."/> - <field xsi:type="ScalarOutputField" name="created_at" type="String" description="Timestamp indicating when a product was created"/> - <field xsi:type="ScalarOutputField" name="updated_at" type="String" description="The timestamp indicating when the product was last updated."/> - <field xsi:type="ScalarOutputField" name="country_of_manufacture" type="String" description="The product's country of origin"/> - <field xsi:type="ScalarOutputField" name="type_id" type="String" description="One of 'simple', 'virtual', 'bundle', 'downloadable','grouped', or 'configurable'"/> - <field xsi:type="ScalarArrayOutputField" name="website_ids" itemType="Int" description="An array of website IDs in which the product is available."/> - <field xsi:type="ObjectArrayOutputField" name="category_links" itemType="ProductCategoryLinks" description="An array that contains links to categories the product is assigned to."/> - <field xsi:type="ObjectArrayOutputField" name="product_links" itemType="ProductLinksInterface" description="An array that contains information about products that are related to the current product."/> - <field xsi:type="ObjectArrayOutputField" name="media_gallery_entries" itemType="MediaGalleryEntry" description="An array that contains information about the images and video assigned to this product."/> - <field xsi:type="ObjectArrayOutputField" name="tier_prices" itemType="ProductTierPrices" description="An array that defines tier prices for the item."/> - <field xsi:type="ObjectOutputField" name="price" type="ProductPrices" description="The price of the item, including the value and the currency code."/> - <field xsi:type="ScalarOutputField" name="gift_message_available" type="String" description="Indicates whether a gift message is available."/> - </type> - <type xsi:type="OutputInterface" name="PhysicalProductInterface" typeResolver="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> - <field xsi:type="ScalarOutputField" name="weight" type="Float" description="The weight of a physical product"/> - </type> - <type xsi:type="OutputInterface" name="CustomizableProductInterface" typeResolver="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> - <field xsi:type="ObjectArrayOutputField" name="options" itemType="CustomizableOptionInterface" description="An array containing information about the customizable options for a product"/> - </type> - <type xsi:type="OutputInterface" name="CustomizableOptionInterface" typeResolver="Magento\CatalogGraphQl\Model\CustomizableOptionTypeResolver"> - <field xsi:type="ScalarOutputField" name="title" type="String" description="The displayed name of the option"/> - <field xsi:type="ScalarOutputField" name="required" type="Boolean" description="Indicates whether the option is required"/> - <field xsi:type="ScalarOutputField" name="sort_order" type="Int" description="The order in which the option is displayed"/> - </type> - <type xsi:type="OutputType" name="VirtualProduct"> - <implements interface="ProductInterface" copyFields="true"/> - <implements interface="CustomizableProductInterface" copyFields="true"/> - </type> - <type xsi:type="OutputType" name="SimpleProduct"> - <implements interface="ProductInterface" copyFields="true"/> - <implements interface="PhysicalProductInterface" copyFields="true"/> - <implements interface="CustomizableProductInterface" copyFields="true"/> - </type> - <type xsi:type="InputType" name="ProductFilterInput"> - <field xsi:type="ObjectInputField" name="name" type="FilterTypeInput" description="The product name. Customers use this name to identify the product."/> - <field xsi:type="ObjectInputField" name="sku" type="FilterTypeInput" description="A number or code assigned to a product to identify the product, options, price, and manufacturer."/> - <field xsi:type="ObjectInputField" name="description" type="FilterTypeInput" description="A detailed information about the product. The value can include simple HTML tags."/> - <field xsi:type="ObjectInputField" name="short_description" type="FilterTypeInput" description="A short description of the product. Its use depends on the theme."/> - <field xsi:type="ObjectInputField" name="price" type="FilterTypeInput" description="The numeric price of the product. Do not include the currency code."/> - <field xsi:type="ObjectInputField" name="special_price" type="FilterTypeInput" description="The discounted price of the product"/> - <field xsi:type="ObjectInputField" name="special_from_date" type="FilterTypeInput" description="The beginning date that a product has a special price."/> - <field xsi:type="ObjectInputField" name="special_to_date" type="FilterTypeInput" description="The end date that a product has a special price."/> - <field xsi:type="ObjectInputField" name="weight" type="FilterTypeInput" description="The weight of the item, in units defined by the store"/> - <field xsi:type="ObjectInputField" name="manufacturer" type="FilterTypeInput" description="The company that created the item"/> - <field xsi:type="ObjectInputField" name="meta_title" type="FilterTypeInput" description="A string that is displayed in the title bar and tab of the browser and in search results lists."/> - <field xsi:type="ObjectInputField" name="meta_keyword" type="FilterTypeInput" description="A comma-separated list of keywords that are visible only to search engines."/> - <field xsi:type="ObjectInputField" name="meta_description" type="FilterTypeInput" description="A brief overview of the product for search results listings. Maximum 255 characters."/> - <field xsi:type="ObjectInputField" name="image" type="FilterTypeInput" description="The relative path for the main image on the product page."/> - <field xsi:type="ObjectInputField" name="small_image" type="FilterTypeInput" description="The file name of a small image, which is used on catalog pages."/> - <field xsi:type="ObjectInputField" name="thumbnail" type="FilterTypeInput" description="The file name of a thumbnail image"/> - <field xsi:type="ObjectInputField" name="tier_price" type="FilterTypeInput" description="The price when tier pricing is in effect and the items purchased threshold has been reached."/> - <field xsi:type="ObjectInputField" name="color" type="FilterTypeInput" description="A number assigned to represent the color"/> - <field xsi:type="ObjectInputField" name="news_from_date" type="FilterTypeInput" description="The beginning date for new product listings, and determines if the product is featured as a new product. Note: The output attribute name is 'new_from_date'."/> - <field xsi:type="ObjectInputField" name="news_to_date" type="FilterTypeInput" description="The end date for new product listings. Note: The output attribute name is 'new_to_date'."/> - <field xsi:type="ObjectInputField" name="custom_design" type="FilterTypeInput" description="A theme that can be applied to the product page."/> - <field xsi:type="ObjectInputField" name="custom_design_from" type="FilterTypeInput" description="The beginning date when a theme is applied to the product page."/> - <field xsi:type="ObjectInputField" name="custom_design_to" type="FilterTypeInput" description="The date at which a theme is no longer applied to the product page."/> - <field xsi:type="ObjectInputField" name="custom_layout_update" type="FilterTypeInput" description="XML code that is applied as a layout update to the product page."/> - <field xsi:type="ObjectInputField" name="page_layout" type="FilterTypeInput" description="The page layout of the product page. Values include '1column-center', '2columns-left', '2columns-right', and '3columns'."/> - <field xsi:type="ObjectInputField" name="category_ids" type="FilterTypeInput" description="An array of category IDs the product belongs to."/> - <field xsi:type="ObjectInputField" name="options_container" type="FilterTypeInput" description="If the product has multiple options, determines where they appear on the product page."/> - <field xsi:type="ObjectInputField" name="required_options" type="FilterTypeInput" description="Indicates whether the product has required options."/> - <field xsi:type="ObjectInputField" name="has_options" type="FilterTypeInput" description="Indicates whether additional attributes have been created for the product."/> - <field xsi:type="ObjectInputField" name="image_label" type="FilterTypeInput" description="The label assigned to a product image."/> - <field xsi:type="ObjectInputField" name="small_image_label" type="FilterTypeInput" description="The label assigned to a product's small image."/> - <field xsi:type="ObjectInputField" name="thumbnail_label" type="FilterTypeInput" description="The label assigned to a product's thumbnail image."/> - <field xsi:type="ObjectInputField" name="created_at" type="FilterTypeInput" description="Timestamp indicating when the product was created"/> - <field xsi:type="ObjectInputField" name="updated_at" type="FilterTypeInput" description="Timestamp indicating when the product was last updated"/> - <field xsi:type="ObjectInputField" name="country_of_manufacture" type="FilterTypeInput" description="The product's country of origin"/> - <field xsi:type="ObjectInputField" name="custom_layout" type="FilterTypeInput" description="The name of a custom layout."/> - <field xsi:type="ObjectInputField" name="gift_message_available" type="FilterTypeInput" description="Indicates whether a gift message is available."/> - <field xsi:type="ObjectInputField" name="or" type="ProductFilterInput" description="The keyword required to perform a logical OR comparison."/> - </type> - <type xsi:type="InputType" name="ProductSortInput"> - <field xsi:type="ObjectInputField" name="name" type="SortEnum" description="The product name. Customers use this name to identify the product."/> - <field xsi:type="ObjectInputField" name="sku" type="SortEnum" description="A number or code assigned to a product to identify the product, options, price, and manufacturer."/> - <field xsi:type="ObjectInputField" name="description" type="SortEnum" description="A detailed information about the product. The value can include simple HTML tags."/> - <field xsi:type="ObjectInputField" name="short_description" type="SortEnum" description="A short description of the product. Its use depends on the theme."/> - <field xsi:type="ObjectInputField" name="price" type="SortEnum" description="The numeric price of the product. Do not include the currency code."/> - <field xsi:type="ObjectInputField" name="special_price" type="SortEnum" description="The discounted price of the product"/> - <field xsi:type="ObjectInputField" name="special_from_date" type="SortEnum" description="The beginning date that a product has a special price."/> - <field xsi:type="ObjectInputField" name="special_to_date" type="SortEnum" description="The end date that a product has a special price."/> - <field xsi:type="ObjectInputField" name="weight" type="SortEnum" description="The weight of the item, in units defined by the store"/> - <field xsi:type="ObjectInputField" name="manufacturer" type="SortEnum" description="The company that created the item"/> - <field xsi:type="ObjectInputField" name="meta_title" type="SortEnum" description="A string that is displayed in the title bar and tab of the browser and in search results lists."/> - <field xsi:type="ObjectInputField" name="meta_keyword" type="SortEnum" description="A comma-separated list of keywords that are visible only to search engines."/> - <field xsi:type="ObjectInputField" name="meta_description" type="SortEnum" description="A brief overview of the product for search results listings. Maximum 255 characters."/> - <field xsi:type="ObjectInputField" name="image" type="SortEnum" description="The relative path for the main image on the product page."/> - <field xsi:type="ObjectInputField" name="small_image" type="SortEnum" description="The file name of a small image, which is used on catalog pages."/> - <field xsi:type="ObjectInputField" name="thumbnail" type="SortEnum" description="The file name of a thumbnail image"/> - <field xsi:type="ObjectInputField" name="tier_price" type="SortEnum" description="The price when tier pricing is in effect and the items purchased threshold has been reached."/> - <field xsi:type="ObjectInputField" name="color" type="SortEnum" description="A number assigned to represent the color"/> - <field xsi:type="ObjectInputField" name="news_from_date" type="SortEnum" description="The beginning date for new product listings, and determines if the product is featured as a new product. Note: The output attribute name is 'new_from_date'."/> - <field xsi:type="ObjectInputField" name="news_to_date" type="SortEnum" description="The end date for new product listings. Note: The output attribute name is 'new_to_date'."/> - <field xsi:type="ObjectInputField" name="custom_design" type="SortEnum" description="A theme that can be applied to the product page."/> - <field xsi:type="ObjectInputField" name="custom_design_from" type="SortEnum" description="The beginning date when a theme is applied to the product page."/> - <field xsi:type="ObjectInputField" name="custom_design_to" type="SortEnum" description="The date at which a theme is no longer applied to the product page."/> - <field xsi:type="ObjectInputField" name="custom_layout_update" type="SortEnum" description="XML code that is applied as a layout update to the product page."/> - <field xsi:type="ObjectInputField" name="page_layout" type="SortEnum" description="The page layout of the product page. Values include '1column-center', '2columns-left', '2columns-right', and '3columns'."/> - <field xsi:type="ObjectInputField" name="category_ids" type="SortEnum" description="An array of category IDs the product belongs to."/> - <field xsi:type="ObjectInputField" name="options_container" type="SortEnum" description="If the product has multiple options, determines where they appear on the product page."/> - <field xsi:type="ObjectInputField" name="required_options" type="SortEnum" description="Indicates whether the product has required options."/> - <field xsi:type="ObjectInputField" name="has_options" type="SortEnum" description="Indicates whether additional attributes have been created for the product."/> - <field xsi:type="ObjectInputField" name="image_label" type="SortEnum" description="The label assigned to a product image."/> - <field xsi:type="ObjectInputField" name="small_image_label" type="SortEnum" description="The label assigned to a product's small image."/> - <field xsi:type="ObjectInputField" name="thumbnail_label" type="SortEnum" description="The label assigned to a product's thumbnail image."/> - <field xsi:type="ObjectInputField" name="created_at" type="SortEnum" description="Timestamp indicating when the product was created"/> - <field xsi:type="ObjectInputField" name="updated_at" type="SortEnum" description="Timestamp indicating when the product was last updated"/> - <field xsi:type="ObjectInputField" name="country_of_manufacture" type="SortEnum" description="The product's country of origin"/> - <field xsi:type="ObjectInputField" name="custom_layout" type="SortEnum" description="The name of a custom layout."/> - <field xsi:type="ObjectInputField" name="gift_message_available" type="SortEnum" description="Indicates whether a gift message is available."/> - </type> - <type xsi:type="OutputType" name="Products"> - <field xsi:type="ObjectArrayOutputField" name="items" itemType="ProductInterface" description="An array of products that match the specified search criteria.."/> - <field xsi:type="ObjectOutputField" name="page_info" type="SearchResultPageInfo" description="An object that includes the `page_info` and `currentPage` values specified in the query"/> - <field xsi:type="ScalarOutputField" name="total_count" type="Int" description="The number of products returned."/> - </type> - <type xsi:type="OutputType" name="MediaGalleryEntry"> - <field xsi:type="ScalarOutputField" name="id" type="Int" description="The identifier assigned to the object"/> - <field xsi:type="ScalarOutputField" name="media_type" type="String" description=" 'image' or 'video'"/> - <field xsi:type="ScalarOutputField" name="label" type="String" description="The the 'alt' text displayed on the UI when the user points to the image"/> - <field xsi:type="ScalarOutputField" name="position" type="Int" description="The media item's position after it has been sorted."/> - <field xsi:type="ScalarOutputField" name="disabled" type="Boolean" description="Whether the image is hidden from view"/> - <field xsi:type="ScalarArrayOutputField" name="types" itemType="String" description="Array of image types. It can have the following values: `image`, `small_image`, `thumbnail`"/> - <field xsi:type="ScalarOutputField" name="file" type="String" description="The path of the image on the server"/> - <field xsi:type="ObjectOutputField" name="content" type="ProductMediaGalleryEntriesContent" description="An array that contains information about images"/> - <field xsi:type="ObjectOutputField" name="video_content" type="ProductMediaGalleryEntriesVideoContent" description="An array that contains information about videos"/> - </type> - <type xsi:type="OutputType" name="ProductMediaGalleryEntriesContent"> - <field xsi:type="ScalarOutputField" name="base64_encoded_data" type="String" description="The image in base64 format"/> - <field xsi:type="ScalarOutputField" name="type" type="String" description="The MIME type of the file, such as 'image/png'"/> - <field xsi:type="ScalarOutputField" name="name" type="String" description="The file name of the image"/> - </type> - <type xsi:type="OutputType" name="ProductMediaGalleryEntriesVideoContent"> - <field xsi:type="ScalarOutputField" name="media_type" type="String" description="Must be 'external-video"/> - <field xsi:type="ScalarOutputField" name="video_provider" type="String" description="Describes the video source"/> - <field xsi:type="ScalarOutputField" name="video_url" type="String" description="The URL to the video"/> - <field xsi:type="ScalarOutputField" name="video_title" type="String" description="The title of the video"/> - <field xsi:type="ScalarOutputField" name="video_description" type="String" description="A description of the video"/> - <field xsi:type="ScalarOutputField" name="video_metadata" type="String" description="Optional data about the video"/> - </type> - <type xsi:type="OutputType" name="CustomizableFieldOption"> - <implements interface="CustomizableOptionInterface" copyFields="true"/> - <field xsi:type="ObjectOutputField" name="value" type="CustomizableFieldValue" description="An object that defines a text field."/> - <field xsi:type="ScalarOutputField" name="product_sku" type="String" description="The Stock Keeping Unit of the base product"/> - </type> - <type xsi:type="OutputType" name="CustomizableFileOption"> - <implements interface="CustomizableOptionInterface" copyFields="true"/> - <field xsi:type="ObjectOutputField" name="value" type="CustomizableFileValue" description="An object that defines a file value."/> - <field xsi:type="ScalarOutputField" name="product_sku" type="String" description="The Stock Keeping Unit of the base product"/> - </type> - <type xsi:type="OutputType" name="CustomizableDateOption"> - <implements interface="CustomizableOptionInterface" copyFields="true"/> - <field xsi:type="ObjectOutputField" name="value" type="CustomizableDateValue" description="An object that defines a date field in a customizable option."/> - <field xsi:type="ScalarOutputField" name="product_sku" type="String" description="The Stock Keeping Unit of the base product"/> - </type> - <type xsi:type="OutputType" name="CustomizableDropDownOption"> - <implements interface="CustomizableOptionInterface" copyFields="true"/> - <field xsi:type="ObjectArrayOutputField" name="value" itemType="CustomizableDropDownValue" description="An array that defines the set of options for a drop down menu."/> - </type> - <type xsi:type="OutputType" name="CustomizableRadioOption"> - <implements interface="CustomizableOptionInterface" copyFields="true"/> - <field xsi:type="ObjectArrayOutputField" name="value" itemType="CustomizableRadioValue" description="An array that defines a set of radio buttons."/> - </type> - <type xsi:type="OutputType" name="CustomizableAreaOption"> - <implements interface="CustomizableOptionInterface" copyFields="true"/> - <field xsi:type="ObjectOutputField" name="value" type="CustomizableAreaValue" description="An object that defines a text area."/> - <field xsi:type="ScalarOutputField" name="product_sku" type="String" description="The Stock Keeping Unit of the base product"/> - </type> - <type xsi:type="OutputType" name="CustomizableFieldValue"> - <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price of the custom value."/> - <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="FIXED, PERCENT, or DYNAMIC"/> - <field xsi:type="ScalarOutputField" name="sku" type="String" description="The Stock Keeping Unit for this option"/> - <field xsi:type="ScalarOutputField" name="max_characters" type="Int" description="The maximum number of characters that can be entered for this customizable option"/> - </type> - <type xsi:type="OutputType" name="CustomizableFileValue"> - <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price assigned to this option"/> - <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="FIXED, PERCENT, or DYNAMIC"/> - <field xsi:type="ScalarOutputField" name="sku" type="String" description="The Stock Keeping Unit for this option"/> - <field xsi:type="ScalarOutputField" name="file_extension" type="String" description="The file extension to accept"/> - <field xsi:type="ScalarOutputField" name="image_size_x" type="Int" description="The maximum width of an image"/> - <field xsi:type="ScalarOutputField" name="image_size_y" type="Int" description="The maximum height of an image"/> - </type> - <type xsi:type="OutputType" name="CustomizableDateValue"> - <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price assigned to this option"/> - <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="FIXED, PERCENT, or DYNAMIC"/> - <field xsi:type="ScalarOutputField" name="sku" type="String" description="The Stock Keeping Unit for this option"/> - </type> - <type xsi:type="OutputType" name="CustomizableDropDownValue"> - <field xsi:type="ScalarOutputField" name="option_type_id" type="Int" description="The ID assigned to the value."/> - <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price assigned to this option"/> - <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="FIXED, PERCENT, or DYNAMIC"/> - <field xsi:type="ScalarOutputField" name="sku" type="String" description="The Stock Keeping Unit for this option"/> - <field xsi:type="ScalarOutputField" name="title" type="String" description="The display name for this option"/> - <field xsi:type="ScalarOutputField" name="sort_order" type="Int" description="The order in which the option is displayed"/> - </type>DY - <type xsi:type="OutputType" name="CustomizableRadioValue"> - <field xsi:type="ScalarOutputField" name="option_type_id" type="Int" description="The ID assigned to the value."/> - <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price assigned to this option"/> - <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="FIXED, PERCENT, or DYNAMIC"/> - <field xsi:type="ScalarOutputField" name="sku" type="String" description="The Stock Keeping Unit for this option"/> - <field xsi:type="ScalarOutputField" name="title" type="String" description="The display name for this option"/> - <field xsi:type="ScalarOutputField" name="sort_order" type="Int" description="The order in which the option is displayed"/> - </type> - <type xsi:type="OutputType" name="CustomizableAreaValue"> - <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price assigned to this option"/> - <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="FIXED, PERCENT, or DYNAMIC"/> - <field xsi:type="ScalarOutputField" name="sku" type="String" description="The Stock Keeping Unit for this option"/> - <field xsi:type="ScalarOutputField" name="max_characters" type="Int" description="The maximum number of characters that can be entered for this customizable option"/> - </type> - <type xsi:type="Enum" name="PriceTypeEnum"> - <item name="fixed">FIXED</item> - <item name="percent">PERCENT</item> - <item name="dynamic">DYNAMIC</item> - </type> -</config> diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphql b/app/code/Magento/CatalogGraphQl/etc/schema.graphql new file mode 100644 index 0000000000000..e144ecca0f020 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphql @@ -0,0 +1,599 @@ +type Query { + products(search: String, filter: ProductFilterInput, pageSize: Int, currentPage: Int, sort: ProductSortInput): Products @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") +} + +enum CurrencyEnum { + AFN + ALL + AZN + DZD + AOA + ARS + AMD + AWG + AUD + BSD + BHD + BDT + BBD + BYR + BZD + BMD + BTN + BOB + BAM + BWP + BRL + GBP + BND + BGN + BUK + BIF + KHR + CAD + CVE + CZK + KYD + GQE + CLP + CNY + COP + KMF + CDF + CRC + HRK + CUP + DKK + DJF + DOP + XCD + EGP + SVC + ERN + EEK + ETB + EUR + FKP + FJD + GMD + GEK + GEL + GHS + GIP + GTQ + GNF + GYD + HTG + HNL + HKD + HUF + ISK + INR + IDR + IRR + IQD + ILS + JMD + JPY + JOD + KZT + KES + KWD + KGS + LAK + LVL + LBP + LSL + LRD + LYD + LTL + MOP + MKD + MGA + MWK + MYR + MVR + LSM + MRO + MUR + MXN + MDL + MNT + MAD + MZN + MMK + NAD + NPR + ANG + YTL + NZD + NIC + NGN + KPW + NOK + OMR + PKR + PAB + PGK + PYG + PEN + PHP + PLN + QAR + RHD + RON + RUB + RWF + SHP + STD + SAR + RSD + SCR + SLL + SGD + SKK + SBD + SOS + ZAR + KRW + LKR + SDG + SRD + SZL + SEK + CHF + SYP + TWD + TJS + TZS + THB + TOP + TTD + TND + TMM + USD + UGX + UAH + AED + UYU + UZS + VUV + VEB + VEF + VND + CHE + CHW + XOF + WST + YER + ZMK + ZWD + TRY + AZM + ROL + TRL + XPF +} + +type Price { + amount: Money + adjustments: [PriceAdjustment] +} + +type PriceAdjustment { + amount: Money + code: PriceAdjustmentCodesEnum + description: PriceAdjustmentDescriptionEnum +} + +enum PriceAdjustmentCodesEnum { + TAX +} + +enum PriceAdjustmentDescriptionEnum { + INCLUDED + EXCLUDED +} + +enum PriceTypeEnum { + FIXED + PERCENT + DYNAMIC +} + +type Money { + value: Float + currency: CurrencyEnum +} + +type ProductPrices { + minimalPrice: Price + maximalPrice: Price + regularPrice: Price +} + +type ProductCategoryLinks { + position: Int + category_id: String +} + + +type ProductLinks implements ProductLinksInterface { + sku: String + link_type: String + linked_product_sku: String + linked_product_type: String + position: Int +} + +interface ProductLinksInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductLinkTypeResolverComposite") { + sku: String + link_type: String + linked_product_sku: String + linked_product_type: String + position: Int +} + +type ProductTierPrices { + customer_group_id: String + qty: Float + value: Float + percentage_value: Float + website_id: Float +} + +interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") { + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + manufacturer: Int +} + +interface PhysicalProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") { + weight: Float +} + + +type CustomizableAreaOption implements CustomizableOptionInterface { + value: CustomizableAreaValue + product_sku: String + title: String + required: Boolean + sort_order: Int +} + +type CustomizableAreaValue { + price: Float + price_type: PriceTypeEnum + sku: String + max_characters: Int +} + +type CustomizableDateOption implements CustomizableOptionInterface { + value: CustomizableDateValue + product_sku: String + title: String + required: Boolean + sort_order: Int +} + +type CustomizableDateValue { + price: Float + price_type: PriceTypeEnum + sku: String +} + +type CustomizableDropDownOption implements CustomizableOptionInterface { + value: [CustomizableDropDownValue] + title: String + required: Boolean + sort_order: Int +} + +type CustomizableDropDownValue { + option_type_id: Int + price: Float + price_type: PriceTypeEnum + sku: String + title: String + sort_order: Int +} + +type CustomizableFieldOption implements CustomizableOptionInterface { + value: CustomizableFieldValue + product_sku: String + title: String + required: Boolean + sort_order: Int +} + +type CustomizableFieldValue { + price: Float + price_type: PriceTypeEnum + sku: String + max_characters: Int +} + +type CustomizableFileOption implements CustomizableOptionInterface { + value: CustomizableFileValue + product_sku: String + title: String + required: Boolean + sort_order: Int +} + +type CustomizableFileValue { + price: Float + price_type: PriceTypeEnum + sku: String + file_extension: String + image_size_x: Int + image_size_y: Int +} + +interface CustomizableOptionInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CustomizableOptionTypeResolver") { + title: String + required: Boolean + sort_order: Int +} + +interface CustomizableProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") { + options: [CustomizableOptionInterface] +} + +type CustomizableRadioOption implements CustomizableOptionInterface { + value: [CustomizableRadioValue] + title: String + required: Boolean + sort_order: Int +} + +type CustomizableRadioValue { + option_type_id: Int + price: Float + price_type: PriceTypeEnum + sku: String + title: String + sort_order: Int +} + +type VirtualProduct implements ProductInterface, CustomizableProductInterface { + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + options: [CustomizableOptionInterface] + manufacturer: Int +} + +type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface { + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + weight: Float + options: [CustomizableOptionInterface] + manufacturer: Int +} + +type Products { + items: [ProductInterface] + page_info: SearchResultPageInfo + total_count: Int +} + + +input ProductFilterInput { + name: FilterTypeInput + sku: FilterTypeInput + description: FilterTypeInput + short_description: FilterTypeInput + price: FilterTypeInput + special_price: FilterTypeInput + special_from_date: FilterTypeInput + special_to_date: FilterTypeInput + weight: FilterTypeInput + manufacturer: FilterTypeInput + meta_title: FilterTypeInput + meta_keyword: FilterTypeInput + meta_description: FilterTypeInput + image: FilterTypeInput + small_image: FilterTypeInput + thumbnail: FilterTypeInput + tier_price: FilterTypeInput + news_from_date: FilterTypeInput + news_to_date: FilterTypeInput + custom_design: FilterTypeInput + custom_design_from: FilterTypeInput + custom_design_to: FilterTypeInput + custom_layout_update: FilterTypeInput + page_layout: FilterTypeInput + category_ids: FilterTypeInput + options_container: FilterTypeInput + required_options: FilterTypeInput + has_options: FilterTypeInput + image_label: FilterTypeInput + small_image_label: FilterTypeInput + thumbnail_label: FilterTypeInput + created_at: FilterTypeInput + updated_at: FilterTypeInput + country_of_manufacture: FilterTypeInput + custom_layout: FilterTypeInput + gift_message_available: FilterTypeInput + or: ProductFilterInput +} + +type ProductMediaGalleryEntriesContent { + base64_encoded_data: String + type: String + name: String +} + +type ProductMediaGalleryEntriesVideoContent { + media_type: String + video_provider: String + video_url: String + video_title: String + video_description: String + video_metadata: String +} + +input ProductSortInput { + name: SortEnum + sku: SortEnum + description: SortEnum + short_description: SortEnum + price: SortEnum + special_price: SortEnum + special_from_date: SortEnum + special_to_date: SortEnum + weight: SortEnum + manufacturer: SortEnum + meta_title: SortEnum + meta_keyword: SortEnum + meta_description: SortEnum + image: SortEnum + small_image: SortEnum + thumbnail: SortEnum + tier_price: SortEnum + news_from_date: SortEnum + news_to_date: SortEnum + custom_design: SortEnum + custom_design_from: SortEnum + custom_design_to: SortEnum + custom_layout_update: SortEnum + page_layout: SortEnum + category_ids: SortEnum + options_container: SortEnum + required_options: SortEnum + has_options: SortEnum + image_label: SortEnum + small_image_label: SortEnum + thumbnail_label: SortEnum + created_at: SortEnum + updated_at: SortEnum + country_of_manufacture: SortEnum + custom_layout: SortEnum + gift_message_available: SortEnum +} + +type MediaGalleryEntry { + id: Int + media_type: String + label: String + position: Int + disabled: Boolean + types: [String] + file: String + content: ProductMediaGalleryEntriesContent + video_content: ProductMediaGalleryEntriesVideoContent +} diff --git a/app/code/Magento/CatalogUrlRewriteGraphQl/etc/graphql.xml b/app/code/Magento/CatalogUrlRewriteGraphQl/etc/graphql.xml deleted file mode 100644 index 58acbffb31987..0000000000000 --- a/app/code/Magento/CatalogUrlRewriteGraphQl/etc/graphql.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> - <type xsi:type="OutputInterface" name="ProductInterface"> - <field xsi:type="ScalarOutputField" name="url_key" type="String" description="The part of a static URL that describes the product or category"/> - <field xsi:type="ScalarOutputField" name="url_path" type="String" description="The URL path"/> - </type> - <type xsi:type="InputType" name="ProductFilterInput"> - <field xsi:type="ObjectInputField" name="url_key" type="FilterTypeInput" description="The part of a static URL that describes the product or category"/> - <field xsi:type="ObjectInputField" name="url_path" type="FilterTypeInput" description="The URL path"/> - </type> - <type xsi:type="InputType" name="ProductSortInput"> - <field xsi:type="ObjectInputField" name="url_key" type="SortEnum" description="The part of a static URL that describes the product or category"/> - <field xsi:type="ObjectInputField" name="url_path" type="SortEnum" description="The URL path"/> - </type> - <type xsi:type="Enum" name="UrlRewriteEntityTypeEnum"> - <item name="product">PRODUCT</item> - <item name="category">CATEGORY</item> - </type> -</config> diff --git a/app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql b/app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql new file mode 100644 index 0000000000000..ee1507c3aea36 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql @@ -0,0 +1,46 @@ + +interface ProductInterface { + url_key: String + url_path: String +} + +type VirtualProduct { + url_key: String + url_path: String +} + +type SimpleProduct { + url_key: String + url_path: String +} + + +type BundleProduct { + url_key: String + url_path: String +} + +type ConfigurableProduct { + url_key: String + url_path: String +} + +type DownloadableProduct { + url_key: String + url_path: String +} + +type GroupedProduct { + url_key: String + url_path: String +} + +input ProductFilterInput { + url_key: FilterTypeInput + url_path: FilterTypeInput +} + +input ProductSortInput { + url_key: SortEnum + url_path: SortEnum +} diff --git a/app/code/Magento/CmsUrlRewriteGraphQl/etc/graphql.xml b/app/code/Magento/CmsUrlRewriteGraphQl/etc/graphql.xml deleted file mode 100644 index e438c4e1acd98..0000000000000 --- a/app/code/Magento/CmsUrlRewriteGraphQl/etc/graphql.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> - <type xsi:type="Enum" name="UrlRewriteEntityTypeEnum"> - <item name="cms_page">CMS_PAGE</item> - </type> -</config> diff --git a/app/code/Magento/CmsUrlRewriteGraphQl/etc/schema.graphql b/app/code/Magento/CmsUrlRewriteGraphQl/etc/schema.graphql new file mode 100644 index 0000000000000..d69641e5a5b6f --- /dev/null +++ b/app/code/Magento/CmsUrlRewriteGraphQl/etc/schema.graphql @@ -0,0 +1,3 @@ +enum UrlRewriteEntityTypeEnum { + CMS_PAGE +} diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml deleted file mode 100644 index 748462cf94772..0000000000000 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> - <type xsi:type="OutputType" name="ConfigurableProduct"> - <implements interface="ProductInterface" copyFields="true"/> - <implements interface="PhysicalProductInterface" copyFields="true"/> - <implements interface="CustomizableProductInterface" copyFields="true"/> - <field xsi:type="ObjectArrayOutputField" name="configurable_product_links" itemType="SimpleProduct"/> - <field xsi:type="ObjectArrayOutputField" name="configurable_product_options" itemType="ConfigurableProductOptions"/> - </type> - <type xsi:type="OutputType" name="ConfigurableProductOptions"> - <field xsi:type="ScalarOutputField" name="id" type="Int" description="The configurable option ID number assigned by the system"/> - <field xsi:type="ScalarOutputField" name="attribute_id" type="String" description="The ID assigned to the attribute"/> - <field xsi:type="ScalarOutputField" name="attribute_code" type="String" description="A string that identifies the attribute"/> - <field xsi:type="ScalarOutputField" name="label" type="String" description="A string that describes the configurable product option. It is displayed on the UI."/> - <field xsi:type="ScalarOutputField" name="position" type="Int" description="A number that indicates the order in which the attribute is displayed."/> - <field xsi:type="ScalarOutputField" name="is_use_default" type="Boolean" description="Indicates whether the option is the default."/> - <field xsi:type="ObjectArrayOutputField" name="values" itemType="ConfigurableProductOptionsValues" description="An array that defines the value_index codes assigned to the configurable product."/> - <field xsi:type="ScalarOutputField" name="product_id" type="Int" description="This is the same as a product's 'id' field."/> - </type> - <type xsi:type="OutputType" name="ConfigurableProductOptionsValues"> - <field xsi:type="ScalarOutputField" name="value_index" type="Int" description="A unique index number assigned to the configurable product option"/> - </type> -</config> diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql b/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql new file mode 100644 index 0000000000000..3724ea4876a02 --- /dev/null +++ b/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql @@ -0,0 +1,62 @@ +type ConfigurableProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface { + configurable_product_links: [SimpleProduct] + configurable_product_options: [ConfigurableProductOptions] + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + weight: Float + options: [CustomizableOptionInterface] + manufacturer: Int +} + +type ConfigurableProductOptions { + id: Int + attribute_id: String + attribute_code: String + label: String + position: Int + is_use_default: Boolean + values: [ConfigurableProductOptionsValues] + product_id: Int +} + +type ConfigurableProductOptionsValues { + value_index: Int +} diff --git a/app/code/Magento/CustomerGraphQl/etc/graphql.xml b/app/code/Magento/CustomerGraphQl/etc/graphql.xml deleted file mode 100644 index 60591326dbd31..0000000000000 --- a/app/code/Magento/CustomerGraphQl/etc/graphql.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> - <type xsi:type="OutputType" name="Query"> - <field xsi:type="ObjectOutputField" name="customer" type="Customer" resolver="Magento\CustomerGraphQl\Model\Resolver\Customer"/> - </type> - <type xsi:type="OutputType" name="Customer"> - <field xsi:type="ScalarOutputField" name="created_at" type="String" description="Timestamp indicating when the customer was created"/> - <field xsi:type="ScalarOutputField" name="group_id" type="Int" description="The group assigned to the user. Default values are 0 (Not logged in), 1 (General), 2 (Wholesale), and 3 (Retailer)"/> - <field xsi:type="ScalarOutputField" name="prefix" type="String" description="An honorific, such as Dr., Mr., or Mrs."/> - <field xsi:type="ScalarOutputField" name="firstname" type="String" description="The customer's first name"/> - <field xsi:type="ScalarOutputField" name="middlename" type="String" description="The customer's middle name"/> - <field xsi:type="ScalarOutputField" name="lastname" type="String" description="The customer's family name"/> - <field xsi:type="ScalarOutputField" name="suffix" type="String" description="A value such as Sr., Jr., or III"/> - <field xsi:type="ScalarOutputField" name="email" type="String" description="The customer's email address. Required"/> - <field xsi:type="ScalarOutputField" name="default_billing" type="String" description="The ID assigned to the billing address"/> - <field xsi:type="ScalarOutputField" name="default_shipping" type="String" description="The ID assigned to the shipping address"/> - <field xsi:type="ScalarOutputField" name="dob" type="String" description="The customer's date of birth"/> - <field xsi:type="ScalarOutputField" name="taxvat" type="String" description="The customer's Tax/VAT number (for corporate customers)"/> - <field xsi:type="ScalarOutputField" name="id" type="Int" description="The ID assigned to the customer"/> - <field xsi:type="ScalarOutputField" name="dob" type="String" description="The customer's date of birth"/> - <field xsi:type="ScalarOutputField" name="is_subscribed" type="Boolean" description="Indicates whether the customer is subscribed to the company's newsletter"/> - <field xsi:type="ObjectArrayOutputField" name="addresses" itemType="CustomerAddress" description="An array of billing and shipping addresses"/> - </type> - <type xsi:type="OutputType" name="CustomerAddress"> - <field xsi:type="ScalarOutputField" name="id" type="Int" description="The ID assigned to the address object"/> - <field xsi:type="ScalarOutputField" name="customer_id" type="Int" description="The same value as a Customer 'id'"/> - <field xsi:type="ObjectOutputField" name="region" type="CustomerAddressRegion" description="An object containing the region name, region code, and region ID"/> - <field xsi:type="ScalarOutputField" name="region_id" type="Int" description="A number that uniquely identifies the state, province, or other area"/> - <field xsi:type="ScalarOutputField" name="country_id" type="String" description="The customer's billing or shipping country."/> - <field xsi:type="ScalarArrayOutputField" name="street" itemType="String" description="An array of strings that define the street number and name"/> - <field xsi:type="ScalarOutputField" name="company" type="String" description="The customer's company"/> - <field xsi:type="ScalarOutputField" name="telephone" type="String" description="The telephone number"/> - <field xsi:type="ScalarOutputField" name="fax" type="String" description="The fax number"/> - <field xsi:type="ScalarOutputField" name="postcode" type="String" description="The customer's ZIP or postal code"/> - <field xsi:type="ScalarOutputField" name="city" type="String" description="The city or town"/> - <field xsi:type="ScalarOutputField" name="firstname" type="String" description=" The first name of the person associated with the shipping/billing address"/> - <field xsi:type="ScalarOutputField" name="lastname" type="String" description=" The family name of the person associated with the shipping/billing address"/> - <field xsi:type="ScalarOutputField" name="middlename" type="String" description=" The middle name of the person associated with the shipping/billing address"/> - <field xsi:type="ScalarOutputField" name="prefix" type="String" description="An honorific, such as Dr., Mr., or Mrs."/> - <field xsi:type="ScalarOutputField" name="suffix" type="String" description="A value such as Sr., Jr., III, etc."/> - <field xsi:type="ScalarOutputField" name="vat_id" type="String" description="The customer's Tax/VAT number (for corporate customers)"/> - <field xsi:type="ScalarOutputField" name="default_shipping" type="Boolean" description="Indicates whether the address is the default shipping address"/> - <field xsi:type="ScalarOutputField" name="default_billing" type="Boolean" description="Indicates whether the address is the default billing address"/> - </type> - <type xsi:type="OutputType" name="CustomerAddressRegion"> - <field xsi:type="ScalarOutputField" name="region_code" type="String" description="An abbreviation representing the state or province, such as NY"/> - <field xsi:type="ScalarOutputField" name="region" type="String" description="The full name of a region or province, such as New York"/> - <field xsi:type="ScalarOutputField" name="region_id" type="Int" description="An integer that maps to the state or province, such as 43"/> - </type> -</config> diff --git a/app/code/Magento/CustomerGraphQl/etc/schema.graphql b/app/code/Magento/CustomerGraphQl/etc/schema.graphql index 46840b9f3e6af..69c0c9366b62f 100644 --- a/app/code/Magento/CustomerGraphQl/etc/schema.graphql +++ b/app/code/Magento/CustomerGraphQl/etc/schema.graphql @@ -2,10 +2,6 @@ type Query { customer: Customer @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\Customer") } -type Products { - testCustomizationFromCustomerConfig: String -} - type Customer { created_at: String group_id: Int @@ -46,3 +42,9 @@ type CustomerAddress { default_billing: Boolean } +type CustomerAddressRegion { + region_code: String + region: String + region_id: Int +} + diff --git a/app/code/Magento/DownloadableGraphQl/etc/graphql.xml b/app/code/Magento/DownloadableGraphQl/etc/graphql.xml deleted file mode 100644 index 7e029c4cc174a..0000000000000 --- a/app/code/Magento/DownloadableGraphQl/etc/graphql.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> - <type xsi:type="OutputType" name="DownloadableProduct"> - <implements interface="ProductInterface" copyFields="true"/> - <implements interface="CustomizableProductInterface" copyFields="true"/> - <field xsi:type="ObjectArrayOutputField" name="downloadable_product_samples" itemType="DownloadableProductSamples" description="An array containing information about samples of this downloadable product."/> - <field xsi:type="ObjectArrayOutputField" name="downloadable_product_links" itemType="DownloadableProductLinks" description="An array containing information about the links for this downloadable product."/> - <field xsi:type="ObjectOutputField" name="links_purchased_separately" type="Int" description="A value of 1 indicates that each link in the array must be purchased separately."/> - <field xsi:type="ObjectOutputField" name="links_title" type="String" description="The heading above the list of downloadable products"/> - </type> - <type xsi:type="OutputType" name="DownloadableProductSamples"> - <field xsi:type="ObjectOutputField" name="id" type="Int" description="The unique ID for the downloadable product sample"/> - <field xsi:type="ObjectOutputField" name="title" type="String" description="The display name of the sample"/> - <field xsi:type="ObjectOutputField" name="sort_order" type="Int" description="A number indicating the sort order."/> - <field xsi:type="ObjectOutputField" name="sample_type" type="DownloadableFileTypeEnum" description="Either FILE or URL"/> - <field xsi:type="ObjectOutputField" name="sample_file" type="String" description="The relative path to the downloadable sample"/> - <field xsi:type="ObjectOutputField" name="sample_url" type="String" description="The relative URL to the downloadable sample"/> - </type> - <type xsi:type="OutputType" name="DownloadableProductLinks"> - <field xsi:type="ObjectOutputField" name="id" type="Int" description="The unique ID for the link to the downloadable product"/> - <field xsi:type="ObjectOutputField" name="title" type="String" description="The display name of the link"/> - <field xsi:type="ObjectOutputField" name="sort_order" type="Int" description="A number indicating the sort order."/> - <field xsi:type="ObjectOutputField" name="is_shareable" type="Boolean" description="Indicates whether the link is shareable"/> - <field xsi:type="ObjectOutputField" name="price" type="Float" description="The price of the downloadable product"/> - <field xsi:type="ObjectOutputField" name="number_of_downloads" type="Int" description="The maximum number of times the product can be downloaded. A value of 0 means unlimited."/> - <field xsi:type="ObjectOutputField" name="link_type" type="DownloadableFileTypeEnum" description="Either FILE or URL"/> - <field xsi:type="ObjectOutputField" name="sample_type" type="DownloadableFileTypeEnum" description="Either FILE or URL"/> - <field xsi:type="ObjectOutputField" name="sample_file" type="String" description="The relative path to the downloadable sample"/> - <field xsi:type="ObjectOutputField" name="sample_url" type="String" description="The relative URL to the downloadable sample"/> - </type> - <type xsi:type="Enum" name="DownloadableFileTypeEnum"> - <item name="file">FILE</item> - <item name="url">URL</item> - </type> -</config> diff --git a/app/code/Magento/DownloadableGraphQl/etc/schema.graphql b/app/code/Magento/DownloadableGraphQl/etc/schema.graphql new file mode 100644 index 0000000000000..a01bc0bb9eb2e --- /dev/null +++ b/app/code/Magento/DownloadableGraphQl/etc/schema.graphql @@ -0,0 +1,75 @@ +type DownloadableProduct implements ProductInterface, CustomizableProductInterface { + downloadable_product_samples: [DownloadableProductSamples] + downloadable_product_links: [DownloadableProductLinks] + links_purchased_separately: Int + links_title: String + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + options: [CustomizableOptionInterface] + manufacturer: Int +} + +enum DownloadableFileTypeEnum { + FILE + URL +} + +type DownloadableProductLinks { + id: Int + title: String + sort_order: Int + is_shareable: Boolean + price: Float + number_of_downloads: Int + link_type: DownloadableFileTypeEnum + sample_type: DownloadableFileTypeEnum + sample_file: String + sample_url: String +} + +type DownloadableProductSamples { + id: Int + title: String + sort_order: Int + sample_type: DownloadableFileTypeEnum + sample_file: String + sample_url: String +} diff --git a/app/code/Magento/EavGraphQl/etc/graphql.xml b/app/code/Magento/EavGraphQl/etc/graphql.xml deleted file mode 100644 index 4f71a4fa89985..0000000000000 --- a/app/code/Magento/EavGraphQl/etc/graphql.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> - <type xsi:type="OutputType" name="Query"> - <field xsi:type="ObjectOutputField" name="customAttributeMetadata" type="CustomAttributeMetadata" resolver="Magento\EavGraphQl\Model\Resolver\CustomAttributeMetadata"> - <argument xsi:type="ObjectArrayArgument" name="attributes" itemType="AttributeInput" itemsRequired="true" required="true"/> - </field> - </type> - <type xsi:type="OutputType" name="CustomAttributeMetadata"> - <field xsi:type="ObjectArrayOutputField" name="items" itemType="Attribute" description="An array of items that match the search criteria"/> - </type> - <type xsi:type="OutputType" name="Attribute"> - <field xsi:type="ScalarOutputField" name="attribute_code" type="String" description="The unique identifier for an attribute code. This value should be in lowercase letters without spaces."/> - <field xsi:type="ScalarOutputField" name="entity_type" type="String" description="The type of entity that defines the attribute."/> - <field xsi:type="ScalarOutputField" name="attribute_type" type="String" description="The data type of the attribute"/> - </type> - <type xsi:type="InputType" name="AttributeInput"> - <field xsi:type="ScalarInputField" name="attribute_code" type="String" description="The unique identifier for an attribute code. This value should be in lowercase letters without spaces."/> - <field xsi:type="ScalarInputField" name="entity_type" type="String" description="The type of entity that defines the attribute."/> - </type> -</config> diff --git a/app/code/Magento/EavGraphQl/etc/schema.graphql b/app/code/Magento/EavGraphQl/etc/schema.graphql new file mode 100644 index 0000000000000..3cd3253778d6b --- /dev/null +++ b/app/code/Magento/EavGraphQl/etc/schema.graphql @@ -0,0 +1,18 @@ +type Query { + customAttributeMetadata(attributes: [AttributeInput!]!): CustomAttributeMetadata @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata") +} + +type CustomAttributeMetadata { + items: [Attribute] +} + +type Attribute { + attribute_code: String + entity_type: String + attribute_type: String +} + +input AttributeInput { + attribute_code: String + entity_type: String +} diff --git a/app/code/Magento/GraphQl/etc/graphql.xml b/app/code/Magento/GraphQl/etc/graphql.xml deleted file mode 100644 index c7833be0a5d77..0000000000000 --- a/app/code/Magento/GraphQl/etc/graphql.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> - <type xsi:type="OutputType" name="Query" /> - <type xsi:type="InputType" name="FilterTypeInput"> - <field xsi:type="ScalarInputField" name="eq" type="String" description="Equals"/> - <field xsi:type="ScalarArrayInputField" name="finset" itemType="String" description="Search for a value within a set of values"/> - <field xsi:type="ScalarInputField" name="from" type="String" description="The beginning of a range"/> - <field xsi:type="ScalarInputField" name="gt" type="String" description="Greater than"/> - <field xsi:type="ScalarInputField" name="gteq" type="String" description="Greater than or equal to"/> - <field xsi:type="ScalarArrayInputField" name="in" itemType="String" description="In. The value can contain a comma-separated list of values."/> - <field xsi:type="ScalarInputField" name="like" type="String" description=" Like. The value can contain the SQL wildcard characters when like is specified."/> - <field xsi:type="ScalarInputField" name="lt" type="String" description="Less than"/> - <field xsi:type="ScalarInputField" name="lteq" type="String" description="Less than or equal to"/> - <field xsi:type="ScalarInputField" name="moreq" type="String" description="More or equal"/> - <field xsi:type="ScalarInputField" name="neq" type="String" description="Not equal"/> - <field xsi:type="ScalarInputField" name="notnull" type="String" description="Not null"/> - <field xsi:type="ScalarInputField" name="null" type="String" description="Null"/> - <field xsi:type="ScalarInputField" name="to" type="String" description="The end of a range. Must be used with 'from'."/> - <field xsi:type="ScalarArrayInputField" name="nin" itemType="String" description="Not in"/> - </type> - <type xsi:type="OutputType" name="SearchResultPageInfo"> - <field xsi:type="ScalarOutputField" name="page_size" type="Int" description="The maximum number of items to return. If no value is specified, 20 items are returned."/> - <field xsi:type="ScalarOutputField" name="current_page" type="Int" description="The page of results to return. If no value is specified, the first page is returned. "/> - </type> - <type xsi:type="Enum" name="SortEnum"> - <item name="asc">ASC</item> - <item name="desc">DESC</item> - </type> -</config> diff --git a/app/code/Magento/GraphQl/etc/schema.graphql b/app/code/Magento/GraphQl/etc/schema.graphql index db58109d85ded..498da368074fb 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphql +++ b/app/code/Magento/GraphQl/etc/schema.graphql @@ -1,529 +1,5 @@ -type CustomerAddressRegion { - region_code: String - region: String - region_id: Int -} - -type Attribute { - attribute_code: String - entity_type: String - attribute_type: String -} - -input AttributeInput { - attribute_code: String - entity_type: String -} - -type BundleItem { - option_id: Int - title: String - required: Boolean - type: String - position: Int - sku: String - options: [BundleItemOption] -} - -type BundleItemOption { - id: Int - label: String - qty: Float - position: Int - is_default: Boolean - price: Float - price_type: PriceTypeEnum - can_change_quantity: Boolean - product: ProductInterface -} - -type BundleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface { - price_view: PriceViewEnum - dynamic_price: Boolean - dynamic_sku: Boolean - ship_bundle_items: ShipBundleItemsEnum - dynamic_weight: Boolean - items: [BundleItem] - url_key: String - url_path: String - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - swatch_image: String - tax_class_id: Int - weight: Float - options: [CustomizableOptionInterface] - manufacturer: Int -} - -type ConfigurableProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface { - configurable_product_links: [SimpleProduct] - configurable_product_options: [ConfigurableProductOptions] - url_key: String - url_path: String - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - swatch_image: String - tax_class_id: Int - weight: Float - options: [CustomizableOptionInterface] - manufacturer: Int -} - -type ConfigurableProductOptions { - id: Int - attribute_id: String - attribute_code: String - label: String - position: Int - is_use_default: Boolean - values: [ConfigurableProductOptionsValues] - product_id: Int -} - -type ConfigurableProductOptionsValues { - value_index: Int -} - -enum CurrencyEnum { - AFN - ALL - AZN - DZD - AOA - ARS - AMD - AWG - AUD - BSD - BHD - BDT - BBD - BYR - BZD - BMD - BTN - BOB - BAM - BWP - BRL - GBP - BND - BGN - BUK - BIF - KHR - CAD - CVE - CZK - KYD - GQE - CLP - CNY - COP - KMF - CDF - CRC - HRK - CUP - DKK - DJF - DOP - XCD - EGP - SVC - ERN - EEK - ETB - EUR - FKP - FJD - GMD - GEK - GEL - GHS - GIP - GTQ - GNF - GYD - HTG - HNL - HKD - HUF - ISK - INR - IDR - IRR - IQD - ILS - JMD - JPY - JOD - KZT - KES - KWD - KGS - LAK - LVL - LBP - LSL - LRD - LYD - LTL - MOP - MKD - MGA - MWK - MYR - MVR - LSM - MRO - MUR - MXN - MDL - MNT - MAD - MZN - MMK - NAD - NPR - ANG - YTL - NZD - NIC - NGN - KPW - NOK - OMR - PKR - PAB - PGK - PYG - PEN - PHP - PLN - QAR - RHD - RON - RUB - RWF - SHP - STD - SAR - RSD - SCR - SLL - SGD - SKK - SBD - SOS - ZAR - KRW - LKR - SDG - SRD - SZL - SEK - CHF - SYP - TWD - TJS - TZS - THB - TOP - TTD - TND - TMM - USD - UGX - UAH - AED - UYU - UZS - VUV - VEB - VEF - VND - CHE - CHW - XOF - WST - YER - ZMK - ZWD - TRY - AZM - ROL - TRL - XPF -} - -type CustomAttributeMetadata { - items: [Attribute] -} - -type CustomizableAreaOption implements CustomizableOptionInterface { - value: CustomizableAreaValue - product_sku: String - title: String - required: Boolean - sort_order: Int -} - -type CustomizableAreaValue { - price: Float - price_type: PriceTypeEnum - sku: String - max_characters: Int -} - -type CustomizableDateOption implements CustomizableOptionInterface { - value: CustomizableDateValue - product_sku: String - title: String - required: Boolean - sort_order: Int -} - -type CustomizableDateValue { - price: Float - price_type: PriceTypeEnum - sku: String -} - -type CustomizableDropDownOption implements CustomizableOptionInterface { - value: [CustomizableDropDownValue] - title: String - required: Boolean - sort_order: Int -} - -type CustomizableDropDownValue { - option_type_id: Int - price: Float - price_type: PriceTypeEnum - sku: String - title: String - sort_order: Int -} - -type CustomizableFieldOption implements CustomizableOptionInterface { - value: CustomizableFieldValue - product_sku: String - title: String - required: Boolean - sort_order: Int -} - -type CustomizableFieldValue { - price: Float - price_type: PriceTypeEnum - sku: String - max_characters: Int -} - -type CustomizableFileOption implements CustomizableOptionInterface { - value: CustomizableFileValue - product_sku: String - title: String - required: Boolean - sort_order: Int -} - -type CustomizableFileValue { - price: Float - price_type: PriceTypeEnum - sku: String - file_extension: String - image_size_x: Int - image_size_y: Int -} - -interface CustomizableOptionInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CustomizableOptionTypeResolver") { - title: String - required: Boolean - sort_order: Int -} - -interface CustomizableProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") { - options: [CustomizableOptionInterface] -} - -type CustomizableRadioOption implements CustomizableOptionInterface { - value: [CustomizableRadioValue] - title: String - required: Boolean - sort_order: Int -} - -type CustomizableRadioValue { - option_type_id: Int - price: Float - price_type: PriceTypeEnum - sku: String - title: String - sort_order: Int -} - -enum DownloadableFileTypeEnum { - FILE - URL -} - -type DownloadableProduct implements ProductInterface, CustomizableProductInterface { - downloadable_product_samples: [DownloadableProductSamples] - downloadable_product_links: [DownloadableProductLinks] - links_purchased_separately: Int - links_title: String - url_key: String - url_path: String - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - swatch_image: String - tax_class_id: Int - options: [CustomizableOptionInterface] - manufacturer: Int -} - -type DownloadableProductLinks { - id: Int - title: String - sort_order: Int - is_shareable: Boolean - price: Float - number_of_downloads: Int - link_type: DownloadableFileTypeEnum - sample_type: DownloadableFileTypeEnum - sample_file: String - sample_url: String -} - -type DownloadableProductSamples { - id: Int - title: String - sort_order: Int - sample_type: DownloadableFileTypeEnum - sample_file: String - sample_url: String -} - -type EntityUrl { - id: Int - canonical_url: String - type: UrlRewriteEntityTypeEnum +type Query { + placeholder: String } input FilterTypeInput { @@ -544,429 +20,12 @@ input FilterTypeInput { nin: [String] } -type GroupedProduct implements ProductInterface, PhysicalProductInterface { - items: [GroupedProductItem] - url_key: String - url_path: String - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - swatch_image: String - tax_class_id: Int - weight: Float - manufacturer: Int -} - -type GroupedProductItem { - qty: Float - position: Int - product: ProductInterface -} - -type MediaGalleryEntry { - id: Int - media_type: String - label: String - position: Int - disabled: Boolean - types: [String] - file: String - content: ProductMediaGalleryEntriesContent - video_content: ProductMediaGalleryEntriesVideoContent -} - -type Money { - value: Float - currency: CurrencyEnum -} - -interface PhysicalProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") { - weight: Float -} - -type Price { - amount: Money - adjustments: [PriceAdjustment] -} - -type PriceAdjustment { - amount: Money - code: PriceAdjustmentCodesEnum - description: PriceAdjustmentDescriptionEnum -} - -enum PriceAdjustmentCodesEnum { - TAX - WEE - WEETAX -} - -enum PriceAdjustmentDescriptionEnum { - INCLUDED - EXCLUDED -} - -enum PriceTypeEnum { - FIXED - PERCENT - DYNAMIC -} - -enum PriceViewEnum { - PRICE_RANGE - AS_LOW_AS -} - -type ProductCategoryLinks { - position: Int - category_id: String -} - -input ProductFilterInput { - url_key: FilterTypeInput - url_path: FilterTypeInput - name: FilterTypeInput - sku: FilterTypeInput - description: FilterTypeInput - short_description: FilterTypeInput - price: FilterTypeInput - special_price: FilterTypeInput - special_from_date: FilterTypeInput - special_to_date: FilterTypeInput - weight: FilterTypeInput - manufacturer: FilterTypeInput - meta_title: FilterTypeInput - meta_keyword: FilterTypeInput - meta_description: FilterTypeInput - image: FilterTypeInput - small_image: FilterTypeInput - thumbnail: FilterTypeInput - tier_price: FilterTypeInput - news_from_date: FilterTypeInput - news_to_date: FilterTypeInput - custom_design: FilterTypeInput - custom_design_from: FilterTypeInput - custom_design_to: FilterTypeInput - custom_layout_update: FilterTypeInput - page_layout: FilterTypeInput - category_ids: FilterTypeInput - options_container: FilterTypeInput - required_options: FilterTypeInput - has_options: FilterTypeInput - image_label: FilterTypeInput - small_image_label: FilterTypeInput - thumbnail_label: FilterTypeInput - created_at: FilterTypeInput - updated_at: FilterTypeInput - country_of_manufacture: FilterTypeInput - custom_layout: FilterTypeInput - gift_message_available: FilterTypeInput - or: ProductFilterInput - swatch_image: FilterTypeInput - tax_class_id: FilterTypeInput -} - -interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") { - url_key: String - url_path: String - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - swatch_image: String - tax_class_id: Int - manufacturer: Int -} - -type ProductLinks implements ProductLinksInterface { - sku: String - link_type: String - linked_product_sku: String - linked_product_type: String - position: Int -} - -interface ProductLinksInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductLinkTypeResolverComposite") { - sku: String - link_type: String - linked_product_sku: String - linked_product_type: String - position: Int -} - -type ProductMediaGalleryEntriesContent { - base64_encoded_data: String - type: String - name: String -} - -type ProductMediaGalleryEntriesVideoContent { - media_type: String - video_provider: String - video_url: String - video_title: String - video_description: String - video_metadata: String -} - -type ProductPrices { - minimalPrice: Price - maximalPrice: Price - regularPrice: Price -} - -input ProductSortInput { - url_key: SortEnum - url_path: SortEnum - name: SortEnum - sku: SortEnum - description: SortEnum - short_description: SortEnum - price: SortEnum - special_price: SortEnum - special_from_date: SortEnum - special_to_date: SortEnum - weight: SortEnum - manufacturer: SortEnum - meta_title: SortEnum - meta_keyword: SortEnum - meta_description: SortEnum - image: SortEnum - small_image: SortEnum - thumbnail: SortEnum - tier_price: SortEnum - news_from_date: SortEnum - news_to_date: SortEnum - custom_design: SortEnum - custom_design_from: SortEnum - custom_design_to: SortEnum - custom_layout_update: SortEnum - page_layout: SortEnum - category_ids: SortEnum - options_container: SortEnum - required_options: SortEnum - has_options: SortEnum - image_label: SortEnum - small_image_label: SortEnum - thumbnail_label: SortEnum - created_at: SortEnum - updated_at: SortEnum - country_of_manufacture: SortEnum - custom_layout: SortEnum - gift_message_available: SortEnum - swatch_image: SortEnum - tax_class_id: SortEnum -} - -type ProductTierPrices { - customer_group_id: String - qty: Float - value: Float - percentage_value: Float - website_id: Float -} - -type Products { - items: [ProductInterface] - page_info: SearchResultPageInfo - total_count: Int -} - -type Query { - products(search: String, filter: ProductFilterInput, pageSize: Int, currentPage: Int, sort: ProductSortInput): Products @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") - customAttributeMetadata(attributes: [AttributeInput!]!): CustomAttributeMetadata @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata") - urlResolver(url: String!): EntityUrl @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\UrlRewrite") -} - type SearchResultPageInfo { page_size: Int current_page: Int } -enum ShipBundleItemsEnum { - TOGETHER - SEPARATELY -} - -type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface { - url_key: String - url_path: String - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - swatch_image: String - tax_class_id: Int - weight: Float - options: [CustomizableOptionInterface] - manufacturer: Int -} - enum SortEnum { ASC DESC } - -enum UrlRewriteEntityTypeEnum { - PRODUCT - CATEGORY - CMS_PAGE -} - -type VirtualProduct implements ProductInterface, CustomizableProductInterface { - url_key: String - url_path: String - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - swatch_image: String - tax_class_id: Int - options: [CustomizableOptionInterface] - manufacturer: Int -} diff --git a/app/code/Magento/GroupedProductGraphQl/etc/graphql.xml b/app/code/Magento/GroupedProductGraphQl/etc/graphql.xml deleted file mode 100644 index aa8dbe8238640..0000000000000 --- a/app/code/Magento/GroupedProductGraphQl/etc/graphql.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> - <type xsi:type="OutputType" name="GroupedProduct"> - <implements interface="ProductInterface" copyFields="true"/> - <implements interface="PhysicalProductInterface" copyFields="true"/> - <field xsi:type="ObjectArrayOutputField" name="items" itemType="GroupedProductItem" description="An array containing grouped product items"/> - </type> - <type xsi:type="OutputType" name="GroupedProductItem"> - <field xsi:type="ScalarOutputField" name="qty" type="Float" description="The quantity of this grouped product item"/> - <field xsi:type="ScalarOutputField" name="position" type="Int" description="The relative position of this item compared to the other group items."/> - <field xsi:type="ObjectOutputField" name="product" type="ProductInterface" description="The ProductInterface object, which contains details about this product option"/> - </type> -</config> diff --git a/app/code/Magento/GroupedProductGraphQl/etc/schema.graphql b/app/code/Magento/GroupedProductGraphQl/etc/schema.graphql new file mode 100644 index 0000000000000..9674d526fc616 --- /dev/null +++ b/app/code/Magento/GroupedProductGraphQl/etc/schema.graphql @@ -0,0 +1,51 @@ +type GroupedProduct implements ProductInterface, PhysicalProductInterface { + items: [GroupedProductItem] + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + weight: Float + manufacturer: Int +} + +type GroupedProductItem { + qty: Float + position: Int + product: ProductInterface +} diff --git a/app/code/Magento/SwatchesGraphQl/etc/graphql.xml b/app/code/Magento/SwatchesGraphQl/etc/graphql.xml deleted file mode 100644 index 1e5e9ac1fb7be..0000000000000 --- a/app/code/Magento/SwatchesGraphQl/etc/graphql.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> - <type xsi:type="OutputInterface" name="ProductInterface"> - <field xsi:type="ScalarOutputField" name="swatch_image" type="String" description="The file name of a swatch image"/> - </type> - <type xsi:type="InputType" name="ProductFilterInput"> - <field xsi:type="ObjectInputField" name="swatch_image" type="FilterTypeInput" description="The file name of a swatch image"/> - </type> - <type xsi:type="InputType" name="ProductSortInput"> - <field xsi:type="ObjectInputField" name="swatch_image" type="SortEnum" description="The file name of a swatch image"/> - </type> -</config> diff --git a/app/code/Magento/SwatchesGraphQl/etc/schema.graphql b/app/code/Magento/SwatchesGraphQl/etc/schema.graphql new file mode 100644 index 0000000000000..f455811125a70 --- /dev/null +++ b/app/code/Magento/SwatchesGraphQl/etc/schema.graphql @@ -0,0 +1,35 @@ +interface ProductInterface { + swatch_image: String +} + +type VirtualProduct { + swatch_image: String +} + +type SimpleProduct { + swatch_image: String +} + +type BundleProduct { + swatch_image: String +} + +type ConfigurableProduct { + swatch_image: String +} + +type DownloadableProduct { + swatch_image: String +} + +type GroupedProduct { + swatch_image: String +} + +input ProductFilterInput { + swatch_image: FilterTypeInput +} + +input ProductSortInput { + swatch_image: SortEnum +} diff --git a/app/code/Magento/TaxGraphQl/etc/graphql.xml b/app/code/Magento/TaxGraphQl/etc/graphql.xml deleted file mode 100644 index 4f8dc3aba3fd9..0000000000000 --- a/app/code/Magento/TaxGraphQl/etc/graphql.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> - <type xsi:type="OutputInterface" name="ProductInterface"> - <field xsi:type="ScalarOutputField" name="tax_class_id" type="Int" description="An ID assigned to a tax class. "/> - </type> - <type xsi:type="InputType" name="ProductFilterInput"> - <field xsi:type="ObjectInputField" name="tax_class_id" type="FilterTypeInput" description="An ID assigned to a tax class."/> - </type> - <type xsi:type="InputType" name="ProductSortInput"> - <field xsi:type="ObjectInputField" name="tax_class_id" type="SortEnum" description="An ID assigned to a tax class."/> - </type> - <type xsi:type="Enum" name="PriceAdjustmentCodesEnum"> - <item name="tax">TAX</item> - </type> -</config> diff --git a/app/code/Magento/TaxGraphQl/etc/schema.graphql b/app/code/Magento/TaxGraphQl/etc/schema.graphql new file mode 100644 index 0000000000000..1edf98b675dfe --- /dev/null +++ b/app/code/Magento/TaxGraphQl/etc/schema.graphql @@ -0,0 +1,35 @@ +type BundleProduct { + tax_class_id: Int +} + +type ConfigurableProduct { + tax_class_id: Int +} + +type DownloadableProduct { + tax_class_id: Int +} + +type GroupedProduct { + tax_class_id: Int +} + +input ProductFilterInput { + tax_class_id: FilterTypeInput +} + +interface ProductInterface { + tax_class_id: Int +} + +input ProductSortInput { + tax_class_id: SortEnum +} + +type SimpleProduct { + tax_class_id: Int +} + +type VirtualProduct { + tax_class_id: Int +} diff --git a/app/code/Magento/UrlRewriteGraphQl/etc/graphql.xml b/app/code/Magento/UrlRewriteGraphQl/etc/graphql.xml deleted file mode 100644 index 4d0786102c18b..0000000000000 --- a/app/code/Magento/UrlRewriteGraphQl/etc/graphql.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> - <type xsi:type="OutputType" name="Query"> - <field xsi:type="ObjectOutputField" name="urlResolver" type="EntityUrl" resolver="Magento\UrlRewriteGraphQl\Model\Resolver\UrlRewrite"> - <argument xsi:type="ScalarArgument" name="url" type="String" required="true"/> - </field> - </type> - <type xsi:type="OutputType" name="EntityUrl"> - <field xsi:type="ScalarOutputField" name="id" type="Int" description="The ID assigned to the object associated with the specified url. This could be a product ID, category ID, or page ID."/> - <field xsi:type="ScalarOutputField" name="canonical_url" type="String" description="The internal relative URL. If the specified url is a redirect, the query returns the redirected URL, not the original."/> - <field xsi:type="ObjectOutputField" name="type" type="UrlRewriteEntityTypeEnum" description="One of PRODUCT, CATEGORY, or CMS_PAGE."/> - </type> - <type xsi:type="Enum" name="UrlRewriteEntityTypeEnum"/> -</config> diff --git a/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphql b/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphql new file mode 100644 index 0000000000000..5063ffdbef6ff --- /dev/null +++ b/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphql @@ -0,0 +1,14 @@ +type EntityUrl { + id: Int + canonical_url: String + type: UrlRewriteEntityTypeEnum +} + +type Query { + urlResolver(url: String!): EntityUrl @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\UrlRewrite") +} + +enum UrlRewriteEntityTypeEnum { + PRODUCT + CATEGORY +} diff --git a/app/code/Magento/WeeeGraphQl/etc/graphql.xml b/app/code/Magento/WeeeGraphQl/etc/graphql.xml deleted file mode 100644 index 31fa4b199371d..0000000000000 --- a/app/code/Magento/WeeeGraphQl/etc/graphql.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - --> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> - <type xsi:type="Enum" name="PriceAdjustmentCodesEnum"> - <item name="wee">WEE</item> - <item name="wee_tax">WEETAX</item> - </type> -</config> diff --git a/app/code/Magento/WeeeGraphQl/etc/schema.graphql b/app/code/Magento/WeeeGraphQl/etc/schema.graphql new file mode 100644 index 0000000000000..b114bccfd925f --- /dev/null +++ b/app/code/Magento/WeeeGraphQl/etc/schema.graphql @@ -0,0 +1,4 @@ +enum PriceAdjustmentCodesEnum { + WEE + WEETAX +} From bbb2c10f0cfafa902114296bc6c8d29fcc715af0 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Fri, 9 Mar 2018 12:32:10 +0200 Subject: [PATCH 041/668] MAGETWO-72861: Category edit performance issue - for 2.3 - Add strict types; - Add scalar type hinting; --- .../Catalog/Model/Category/Product/PositionResolver.php | 4 +++- .../Test/Unit/Model/Category/Product/PositionResolverTest.php | 2 ++ .../CatalogRule/Model/Indexer/IndexBuilder/ProductLoader.php | 4 +++- app/code/Magento/CatalogRule/Plugin/Indexer/Category.php | 2 +- .../Unit/Model/Indexer/IndexBuilder/ProductLoaderTest.php | 1 + .../Observer/CategoryProcessUrlRewriteSavingObserver.php | 2 +- 6 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category/Product/PositionResolver.php b/app/code/Magento/Catalog/Model/Category/Product/PositionResolver.php index 97941f2d23b9f..8dee636799a79 100644 --- a/app/code/Magento/Catalog/Model/Category/Product/PositionResolver.php +++ b/app/code/Magento/Catalog/Model/Category/Product/PositionResolver.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Model\Category\Product; /** @@ -37,7 +39,7 @@ protected function _construct() * @param int $categoryId * @return array */ - public function getPositions(int $categoryId) + public function getPositions(int $categoryId): array { $connection = $this->getConnection(); diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Category/Product/PositionResolverTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Category/Product/PositionResolverTest.php index 9545e5eb4b37d..1ff3a1bae5c28 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Category/Product/PositionResolverTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Category/Product/PositionResolverTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Test\Unit\Model\Category\Product; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; diff --git a/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder/ProductLoader.php b/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder/ProductLoader.php index bce2bea2fd952..61c4791549935 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder/ProductLoader.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder/ProductLoader.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\CatalogRule\Model\Indexer\IndexBuilder; use Magento\Catalog\Api\ProductRepositoryInterface; @@ -42,7 +44,7 @@ public function __construct( * @param array $productIds * @return ProductInterface[] */ - public function getProducts($productIds) + public function getProducts(array $productIds): array { $this->searchCriteriaBuilder->addFilter('entity_id', $productIds, 'in'); $searchCriteria = $this->searchCriteriaBuilder->create(); diff --git a/app/code/Magento/CatalogRule/Plugin/Indexer/Category.php b/app/code/Magento/CatalogRule/Plugin/Indexer/Category.php index 0ea0fdda31958..29fc7c72bfb15 100644 --- a/app/code/Magento/CatalogRule/Plugin/Indexer/Category.php +++ b/app/code/Magento/CatalogRule/Plugin/Indexer/Category.php @@ -36,7 +36,7 @@ public function afterSave( ) { /** @var \Magento\Catalog\Model\Category $result */ $productIds = $result->getAffectedProductIds(); - if ($productIds && !$this->productRuleProcessor->isIndexerScheduled()) { + if (!empty($productIds) && !$this->productRuleProcessor->isIndexerScheduled()) { $this->productRuleProcessor->reindexList($productIds); } return $result; diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilder/ProductLoaderTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilder/ProductLoaderTest.php index 3509128da79da..881c21e3beaa2 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilder/ProductLoaderTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilder/ProductLoaderTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\CatalogRule\Test\Unit\Model\Indexer\IndexBuilder; diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php index 539e5c3f42f15..e2e71ec494ece 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php @@ -85,7 +85,7 @@ public function execute(\Magento\Framework\Event\Observer $observer) $mapsGenerated = false; if ($category->dataHasChangedFor('url_key') || $category->dataHasChangedFor('is_anchor') - || $category->getChangedProductIds() + || !empty($category->getChangedProductIds()) ) { if ($category->dataHasChangedFor('url_key')) { $categoryUrlRewriteResult = $this->categoryUrlRewriteGenerator->generate($category); From 5ce8c6fe07f70060ccbb4ba5e8863d34fd78477c Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Fri, 9 Mar 2018 15:32:20 +0200 Subject: [PATCH 042/668] MAGETWO-72861: Category edit performance issue - for 2.3 - Update unit tests; --- .../Test/Unit/Model/Indexer/IndexBuilder/ProductLoaderTest.php | 2 +- .../CatalogRule/Test/Unit/Model/Indexer/IndexBuilderTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilder/ProductLoaderTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilder/ProductLoaderTest.php index 881c21e3beaa2..0560bc616f9ca 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilder/ProductLoaderTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilder/ProductLoaderTest.php @@ -87,7 +87,7 @@ public function testGetProducts() ->method('getList') ->with($this->searchCriteria) ->willReturn($this->productSearchResultsInterface); - $iterator = new \ArrayIterator([$this->product]); + $iterator = [$this->product]; $this->productSearchResultsInterface->expects($this->once()) ->method('getItems') ->willReturn($iterator); diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilderTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilderTest.php index 8252b512e7810..521e4e1d59897 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilderTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilderTest.php @@ -255,7 +255,7 @@ public function testUpdateCatalogRuleGroupWebsiteData() ->method('getBackend') ->will($this->returnValue($backendModelMock)); - $iterator = new \ArrayIterator([$this->product]); + $iterator = [$this->product]; $this->productLoader->expects($this->once()) ->method('getProducts') ->willReturn($iterator); From f28e00ee45386a93c149288789303c764f46577e Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 9 Mar 2018 17:49:09 -0600 Subject: [PATCH 043/668] MAGETWO-89031: Make all graphql methods to return strict type - adding strict types - removing dependency and Use of graphql webonyx types --- .../Query/BundleProductPostProcessor.php | 2 +- .../ConfigurableProductPostProcessor.php | 2 +- .../Query/GroupedItemsPostProcessor.php | 2 +- .../Model/Resolver/ItemPostProcessor.php | 2 +- .../GraphQl/Config/ArgumentConfig.php | 2 +- .../Framework/GraphQl/Config/FieldConfig.php | 10 ++- .../Framework/GraphQl/Query/EnumLookup.php | 2 +- .../Query/PostFetchProcessorInterface.php | 2 +- .../Framework/GraphQl/SchemaProvider.php | 4 +- .../GraphQl/Type/Definition/BooleanType.php | 7 +- .../GraphQl/Type/Definition/EnumType.php | 2 +- .../GraphQl/Type/Definition/FloatType.php | 7 +- .../GraphQl/Type/Definition/IdType.php | 7 +- .../Type/Definition/InputObjectType.php | 2 +- .../GraphQl/Type/Definition/InputType.php | 15 ++++ .../GraphQl/Type/Definition/IntType.php | 7 +- .../GraphQl/Type/Definition/InterfaceType.php | 2 +- .../GraphQl/Type/Definition/ListOfType.php | 2 +- .../GraphQl/Type/Definition/NonNull.php | 2 +- .../GraphQl/Type/Definition/ObjectType.php | 2 +- .../GraphQl/Type/Definition/OutputType.php | 15 ++++ .../GraphQl/Type/Definition/ScalarTypes.php | 71 +++++++++++++++++++ .../GraphQl/Type/Definition/StringType.php | 7 +- .../GraphQl/Type/Definition/TypeInterface.php | 2 +- .../GraphQl/Type/Entity/DefaultMapper.php | 2 +- .../GraphQl/Type/Entity/MapperInterface.php | 2 +- .../GraphQl/Type/Enum/DataMapperInterface.php | 2 +- .../GraphQl/Type/Enum/DefaultDataMapper.php | 2 +- .../Framework/GraphQl/Type/Enum/Enum.php | 2 +- .../GraphQl/Type/Input/InputMapper.php | 4 +- .../GraphQl/Type/Input/InputObjectType.php | 13 ++-- .../GraphQl/Type/Output/ElementMapper.php | 2 +- .../Output/ElementMapper/Formatter/Fields.php | 14 ++-- .../ElementMapper/Formatter/Interfaces.php | 4 +- .../ElementMapper/Formatter/ResolveType.php | 4 +- .../ElementMapper/FormatterComposite.php | 4 +- .../ElementMapper/FormatterInterface.php | 4 +- .../GraphQl/Type/Output/OutputFactory.php | 2 +- .../Type/Output/OutputInterfaceObject.php | 2 +- .../GraphQl/Type/Output/OutputMapper.php | 8 +-- .../GraphQl/Type/Output/OutputTypeObject.php | 2 +- .../Magento/Framework/GraphQl/Type/Schema.php | 36 ++++++++++ .../Framework/GraphQl/Type/SchemaFactory.php | 2 +- .../Magento/Framework/GraphQl/TypeFactory.php | 68 +++++++++++++----- 44 files changed, 273 insertions(+), 84 deletions(-) create mode 100644 lib/internal/Magento/Framework/GraphQl/Type/Definition/InputType.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Type/Definition/OutputType.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php index 153427923b068..4a2041f3e65b8 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php @@ -74,7 +74,7 @@ public function __construct( * @param array $resultData * @return array */ - public function process(array $resultData) + public function process(array $resultData) : array { $childrenSkus = []; $bundleMap = []; diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/Query/ConfigurableProductPostProcessor.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/Query/ConfigurableProductPostProcessor.php index 0c329aaf4f0fa..91ee78e74631b 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/Query/ConfigurableProductPostProcessor.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/Query/ConfigurableProductPostProcessor.php @@ -61,7 +61,7 @@ public function __construct( * @param array $resultData * @return array */ - public function process(array $resultData) + public function process(array $resultData) : array { $childrenIds = []; foreach ($resultData as $key => $product) { diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php index ddaabb1504ee0..7be9e8e4cf6b9 100644 --- a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php +++ b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php @@ -60,7 +60,7 @@ public function __construct( /** * {@inheritDoc} */ - public function process(array $resultData) + public function process(array $resultData) : array { $childrenSkus = []; foreach ($resultData as $product) { diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/Model/Resolver/ItemPostProcessor.php b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/Model/Resolver/ItemPostProcessor.php index 5805d6a34db08..a619587ac1b44 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/Model/Resolver/ItemPostProcessor.php +++ b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/Model/Resolver/ItemPostProcessor.php @@ -31,7 +31,7 @@ public function __construct(ItemFactory $itemFactory) /** * @inheritDoc */ - public function process(array $resultData) + public function process(array $resultData) : array { /** @var Item $item */ $item = $this->itemFactory->create(); diff --git a/lib/internal/Magento/Framework/GraphQl/Config/ArgumentConfig.php b/lib/internal/Magento/Framework/GraphQl/Config/ArgumentConfig.php index 85dfb29697a41..f0cbd3501649f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/ArgumentConfig.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/ArgumentConfig.php @@ -52,7 +52,7 @@ public function getDefaultValue() * * @return ValueParserInterface|null */ - public function getValueParser() + public function getValueParser() : ?ValueParserInterface { return $this->valueParser; } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/FieldConfig.php b/lib/internal/Magento/Framework/GraphQl/Config/FieldConfig.php index c22c72166cf43..748d1e462dbcb 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/FieldConfig.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/FieldConfig.php @@ -46,7 +46,7 @@ public function __construct(ArgumentConfigFactory $argumentConfigFactory, array * @return ArgumentConfig[] * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ - public function getFieldConfig(string $fieldName, array $arguments) + public function getFieldConfig(string $fieldName, array $arguments) : array { if (isset($this->instances[$fieldName])) { return $this->instances[$fieldName]; @@ -69,7 +69,13 @@ public function getFieldConfig(string $fieldName, array $arguments) } } - private function processConfiguredField(string $fieldName, array $arguments) + /** + * Configure field and create arguments instance + * + * @param string $fieldName + * @param array $arguments + */ + private function processConfiguredField(string $fieldName, array $arguments) : void { $this->instances[$fieldName] = []; foreach ($this->config[$fieldName] as $argumentName => $fieldConfig) { diff --git a/lib/internal/Magento/Framework/GraphQl/Query/EnumLookup.php b/lib/internal/Magento/Framework/GraphQl/Query/EnumLookup.php index 0f45610af097b..85559fc40d6af 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/EnumLookup.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/EnumLookup.php @@ -44,7 +44,7 @@ public function __construct(ConfigInterface $typeConfig, DataMapperInterface $en * @return int|string|bool|float|null * @throws \Magento\Framework\Exception\RuntimeException */ - public function getEnumValueFromField(string $enumName, $fieldValue) + public function getEnumValueFromField(string $enumName, $fieldValue) : string { $priceViewEnum = $this->typeConfig->getTypeStructure($enumName); if ($priceViewEnum instanceof Enum) { diff --git a/lib/internal/Magento/Framework/GraphQl/Query/PostFetchProcessorInterface.php b/lib/internal/Magento/Framework/GraphQl/Query/PostFetchProcessorInterface.php index 2ecf7a2da28ee..a41d1e676d30f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/PostFetchProcessorInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/PostFetchProcessorInterface.php @@ -17,5 +17,5 @@ interface PostFetchProcessorInterface * @param array $resultData * @return array */ - public function process(array $resultData); + public function process(array $resultData) : array; } diff --git a/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php b/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php index def2f99b5635c..6116e0b1139d6 100644 --- a/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php +++ b/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php @@ -6,7 +6,7 @@ namespace Magento\Framework\GraphQl; -use GraphQL\Type\Definition\OutputType; +use Magento\Framework\GraphQl\Type\Definition\OutputType; use Magento\Framework\GraphQl\Config\ConfigInterface; use Magento\Framework\GraphQl\Type\Output\OutputMapper; @@ -41,7 +41,7 @@ public function __construct( /** * Retrieve all type objects generated for a GraphQL schema. * - * @return array + * @return OutputType[] */ public function getTypes() : array { diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/BooleanType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/BooleanType.php index bbac9448db7bc..e905af4d6bcd5 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/BooleanType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/BooleanType.php @@ -9,7 +9,10 @@ /** * Wrapper for GraphQl BooleanType */ -class BooleanType extends \GraphQL\Type\Definition\BooleanType implements TypeInterface +class BooleanType extends \GraphQL\Type\Definition\BooleanType implements InputType, OutputType { - + /** + * @var string + */ + public $name = "Magento_Boolean"; } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/EnumType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/EnumType.php index 4dc8ecc53b9ea..5063220bf8f95 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/EnumType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/EnumType.php @@ -9,7 +9,7 @@ /** * Wrapper for GraphQl EnumType */ -class EnumType extends \GraphQL\Type\Definition\EnumType implements TypeInterface +class EnumType extends \GraphQL\Type\Definition\EnumType implements InputType, OutputType { } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/FloatType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/FloatType.php index 18cf0ac3373b0..10fdc568ce268 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/FloatType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/FloatType.php @@ -9,7 +9,10 @@ /** * Wrapper for GraphQl FloatType */ -class FloatType extends \GraphQL\Type\Definition\FloatType implements TypeInterface +class FloatType extends \GraphQL\Type\Definition\FloatType implements InputType, OutputType { - + /** + * @var string + */ + public $name = "Magento_Float"; } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/IdType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/IdType.php index 3a269817fb9ec..30a8bebdc867a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/IdType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/IdType.php @@ -9,7 +9,10 @@ /** * Wrapper for GraphQl IdType */ -class IdType extends \GraphQL\Type\Definition\IDType implements TypeInterface +class IdType extends \GraphQL\Type\Definition\IDType implements InputType, OutputType { - + /** + * @var string + */ + public $name = "Magento_Id"; } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputObjectType.php index 91e2ab9ba22c3..d9c48754d10c3 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputObjectType.php @@ -9,7 +9,7 @@ /** * Wrapper for GraphQl InputObjectType */ -class InputObjectType extends \GraphQL\Type\Definition\InputObjectType implements TypeInterface +class InputObjectType extends \GraphQL\Type\Definition\InputObjectType implements InputType { } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputType.php new file mode 100644 index 0000000000000..56377dbbc02c2 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputType.php @@ -0,0 +1,15 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Framework\GraphQl\Type\Definition; + +/** + * Interface for GraphQl InputType only used for input + */ +interface InputType extends \GraphQL\Type\Definition\InputType, TypeInterface +{ + +} diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/IntType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/IntType.php index 1849cccccacb1..2e3811efe3015 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/IntType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/IntType.php @@ -9,7 +9,10 @@ /** * Wrapper for GraphQl IntType */ -class IntType extends \GraphQL\Type\Definition\IntType implements TypeInterface +class IntType extends \GraphQL\Type\Definition\IntType implements InputType, OutputType { - + /** + * @var string + */ + public $name = "Magento_Int"; } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/InterfaceType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/InterfaceType.php index fb018a6fd214a..77b16228c1a3c 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/InterfaceType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/InterfaceType.php @@ -9,7 +9,7 @@ /** * Wrapper for GraphQl InterfaceType */ -class InterfaceType extends \GraphQL\Type\Definition\InterfaceType implements TypeInterface +class InterfaceType extends \GraphQL\Type\Definition\InterfaceType implements OutputType { } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ListOfType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ListOfType.php index df9f58a50ce52..e7020433e5c78 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ListOfType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ListOfType.php @@ -9,7 +9,7 @@ /** * Wrapper for GraphQl ListOfType */ -class ListOfType extends \GraphQL\Type\Definition\ListOfType implements TypeInterface +class ListOfType extends \GraphQL\Type\Definition\ListOfType implements InputType, OutputType { } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/NonNull.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/NonNull.php index 40be75a17e8eb..8bab282b2efba 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/NonNull.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/NonNull.php @@ -9,7 +9,7 @@ /** * Wrapper for GraphQl NonNull */ -class NonNull extends \GraphQL\Type\Definition\NonNull implements TypeInterface +class NonNull extends \GraphQL\Type\Definition\NonNull implements InputType, OutputType { } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ObjectType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ObjectType.php index 1b0581678ae7a..22d0c67754c6b 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ObjectType.php @@ -9,7 +9,7 @@ /** * Wrapper for GraphQl ObjectType */ -class ObjectType extends \GraphQL\Type\Definition\ObjectType implements TypeInterface +class ObjectType extends \GraphQL\Type\Definition\ObjectType implements OutputType { } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/OutputType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/OutputType.php new file mode 100644 index 0000000000000..51760385682a8 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/OutputType.php @@ -0,0 +1,15 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Framework\GraphQl\Type\Definition; + +/** + * Interface for GraphQl OutputType only used for output + */ +interface OutputType extends \GraphQL\Type\Definition\OutputType, TypeInterface +{ + +} diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php new file mode 100644 index 0000000000000..65c67a4daa3da --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php @@ -0,0 +1,71 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Framework\GraphQl\Type\Definition; + +/** + * Wrapper for GraphQl ScalarType + */ +class ScalarTypes +{ + /** + * @var string[] + */ + private $scalarTypes = [ + 'Boolean' => BooleanType::class, + 'Float' => FloatType::class, + 'ID' => IdType::class, + 'Int' => IntType::class, + 'String' => StringType::class + ]; + + /** + * @var TypeInterface + */ + private $scalarTypesInstances = [ + + ]; + + /** + * @param string $typeName + * @return bool + */ + public function hasScalarTypeClass(string $typeName) : bool + { + return isset($this->scalarTypes[$typeName]) ? true : false; + } + + /** + * @param string $typeName + * @return string|null + * @throws \LogicException + */ + public function getScalarTypeClass(string $typeName) : string + { + if ($this->hasScalarTypeClass($typeName)) { + return $this->scalarTypes[$typeName]; + } + throw new \LogicException(sprintf('Scalar type class with name %s doesn\'t exist', $typeName)); + } + + /** + * @param string $typeName + * @return TypeInterface|null + * @throws \LogicException + */ + public function getScalarTypeInstance(string $typeName) : TypeInterface + { + if ($this->hasScalarTypeClass($typeName)) { + if (!isset($this->scalarTypesInstances[$typeName])) { + $scalarClassName = $this->getScalarTypeClass($typeName); + $this->scalarTypesInstances[$typeName] = new $scalarClassName(); + } + return $this->scalarTypesInstances[$typeName]; + } else { + throw new \LogicException(sprintf('Scalar type %s doesn\'t exist', $typeName)); + } + } +} diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/StringType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/StringType.php index a8c9520292800..6f48ce84343a5 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/StringType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/StringType.php @@ -9,7 +9,10 @@ /** * Wrapper for GraphQl StringType */ -class StringType extends \GraphQL\Type\Definition\StringType implements TypeInterface +class StringType extends \GraphQL\Type\Definition\StringType implements InputType, OutputType { - + /** + * @var string + */ + public $name = "Magento_String"; } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/TypeInterface.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/TypeInterface.php index 170211b0af6b0..7960b04b6f622 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/TypeInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/TypeInterface.php @@ -7,7 +7,7 @@ namespace Magento\Framework\GraphQl\Type\Definition; /** - * Marker interface for GraphQl Type + * Marker interface for all GraphQl types */ interface TypeInterface { diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Entity/DefaultMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Entity/DefaultMapper.php index 88d06390442a6..0db765ced273c 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Entity/DefaultMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Entity/DefaultMapper.php @@ -27,7 +27,7 @@ public function __construct(array $map) /** * {@inheritDoc} */ - public function getMappedTypes(string $entityName) + public function getMappedTypes(string $entityName) : array { return isset($this->map[$entityName]) ? $this->map[$entityName] : []; } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Entity/MapperInterface.php b/lib/internal/Magento/Framework/GraphQl/Type/Entity/MapperInterface.php index 76c99ccbab3a4..b55db8bf9d68a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Entity/MapperInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Entity/MapperInterface.php @@ -17,5 +17,5 @@ interface MapperInterface * @param string $entityName * @return string[] */ - public function getMappedTypes(string $entityName); + public function getMappedTypes(string $entityName) : array; } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Enum/DataMapperInterface.php b/lib/internal/Magento/Framework/GraphQl/Type/Enum/DataMapperInterface.php index 01ee4edfe6308..2f59364d7480d 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Enum/DataMapperInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Enum/DataMapperInterface.php @@ -17,5 +17,5 @@ interface DataMapperInterface * @param string $enumName * @return string[] */ - public function getMappedEnums(string $enumName); + public function getMappedEnums(string $enumName) : array; } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Enum/DefaultDataMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Enum/DefaultDataMapper.php index c38247e7f0a77..25f084441d864 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Enum/DefaultDataMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Enum/DefaultDataMapper.php @@ -27,7 +27,7 @@ public function __construct(array $map) /** * {@inheritDoc} */ - public function getMappedEnums(string $enumName) + public function getMappedEnums(string $enumName) : array { return isset($this->map[$enumName]) ? $this->map[$enumName] : []; } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php b/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php index e7a7c4fb303f3..8347aaab19c4c 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php @@ -6,7 +6,7 @@ namespace Magento\Framework\GraphQl\Type\Enum; -use GraphQL\Type\Definition\EnumType; +use Magento\Framework\GraphQl\Type\Definition\EnumType; use Magento\Framework\GraphQl\Config\Data\Enum as EnumStructure; class Enum extends EnumType diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php index ff9004f2332a5..821e984db7457 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php @@ -53,7 +53,7 @@ public function __construct( public function getRepresentation(Argument $argument) : InputType { $type = $argument->isList() ? $argument->getItemType() : $argument->getType(); - $instance = $this->typeFactory->createScalar($type); + $instance = $this->typeFactory->getScalar($type); if (!$instance) { $configElement = $this->config->getTypeStructure($type); $instance = $this->inputFactory->create($configElement); @@ -69,7 +69,7 @@ public function getRepresentation(Argument $argument) : InputType public function getFieldRepresentation(string $type) : InputType { - $instance = $this->typeFactory->createScalar($type); + $instance = $this->typeFactory->getScalar($type); if (!$instance) { $configElement = $this->config->getTypeStructure($type); $instance = $this->inputFactory->create($configElement); diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php index cc85a9e9fb752..6e05703d5d22a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php @@ -6,16 +6,17 @@ namespace Magento\Framework\GraphQl\Type\Input; -use GraphQL\Type\Definition\InputType; +use Magento\Framework\GraphQl\Type\Definition\InputType; use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Config\Data\Type as TypeStructure; use Magento\Framework\GraphQl\Type\Definition\TypeInterface; use Magento\Framework\GraphQl\TypeFactory; +use Magento\Framework\GraphQl\Type\Definition\NonNull; /** * Class InputObjectType */ -class InputObjectType extends \GraphQL\Type\Definition\InputObjectType +class InputObjectType extends \Magento\Framework\GraphQl\Type\Definition\InputObjectType { /** * @var TypeFactory @@ -56,9 +57,9 @@ public function __construct( * * @param Field $field * @param InputType $object - * @return TypeInterface|\GraphQL\Type\Definition\Type + * @return TypeInterface|InputType */ - private function processIsNullable(Field $field, InputType $object) + private function processIsNullable(Field $field, InputType $object) : TypeInterface { if ($field->isRequired()) { return $this->typeFactory->createNonNull($object); @@ -71,9 +72,9 @@ private function processIsNullable(Field $field, InputType $object) * * @param Field $field * @param InputType $object - * @return TypeInterface|\GraphQL\Type\Definition\Type + * @return TypeInterface|InputType */ - private function processIsList(Field $field, InputType $object) + private function processIsList(Field $field, InputType $object) : TypeInterface { if ($field->isList()) { return $this->typeFactory->createList($object); diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper.php index a033bd7beda3c..78e43d225e968 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper.php @@ -8,7 +8,7 @@ use Magento\Framework\GraphQl\Config\Data\StructureInterface; use Magento\Framework\GraphQl\Type\Output\ElementMapper\FormatterInterface; -use GraphQL\Type\Definition\OutputType; +use Magento\Framework\GraphQl\Type\Definition\OutputType; /** * Takes types represented with structure objects and maps them to GraphQL type-readable array formats diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php index 72d94b3c33db3..9a0e101093357 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php @@ -6,7 +6,7 @@ namespace Magento\Framework\GraphQl\Type\Output\ElementMapper\Formatter; -use GraphQL\Type\Definition\OutputType; +use Magento\Framework\GraphQl\Type\Definition\OutputType; use Magento\Framework\GraphQl\ArgumentFactory; use Magento\Framework\GraphQl\Config\Data\StructureInterface; use Magento\Framework\GraphQl\Type\Input\InputMapper; @@ -81,7 +81,7 @@ public function __construct( * {@inheritDoc} * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ - public function format(StructureInterface $typeStructure, OutputType $outputType) + public function format(StructureInterface $typeStructure, OutputType $outputType) : array { $config = []; foreach ($typeStructure->getFields() as $field) { @@ -134,9 +134,9 @@ function ($value, $args, $context, $info) use ($resolver, $field) { * * @param Field $field * @param OutputType $object - * @return TypeInterface|\GraphQL\Type\Definition\Type + * @return OutputType */ - private function processIsNullable(Field $field, OutputType $object) + private function processIsNullable(Field $field, OutputType $object) : OutputType { if ($field->isRequired()) { return $this->typeFactory->createNonNull($object); @@ -149,9 +149,9 @@ private function processIsNullable(Field $field, OutputType $object) * * @param Field $field * @param OutputType $object - * @return TypeInterface|\GraphQL\Type\Definition\Type + * @return OutputType */ - private function processIsList(Field $field, OutputType $object) + private function processIsList(Field $field, OutputType $object) : OutputType { if ($field->isList()) { return $this->typeFactory->createList($object); @@ -167,7 +167,7 @@ private function processIsList(Field $field, OutputType $object) * @param OutputType $outputType * @return OutputType */ - private function getFieldType(StructureInterface $typeStructure, Field $field, OutputType $outputType) + private function getFieldType(StructureInterface $typeStructure, Field $field, OutputType $outputType) : OutputType { if ($typeStructure->getName() == $field->getType()) { $type = $outputType; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php index e746a3d3255c7..9a707c44937be 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php @@ -6,7 +6,7 @@ namespace Magento\Framework\GraphQl\Type\Output\ElementMapper\Formatter; -use GraphQL\Type\Definition\OutputType; +use Magento\Framework\GraphQl\Type\Definition\OutputType; use Magento\Framework\GraphQl\Config\Data\StructureInterface; use Magento\Framework\GraphQl\Config\Data\Type; use Magento\Framework\GraphQl\Type\Output\ElementMapper\FormatterInterface; @@ -40,7 +40,7 @@ public function __construct(ObjectManagerInterface $objectManager, OutputMapper /** * {@inheritDoc} */ - public function format(StructureInterface $typeStructure, OutputType $outputType) + public function format(StructureInterface $typeStructure, OutputType $outputType) : array { $config = []; if ($typeStructure instanceof Type && !empty($typeStructure->getInterfaces())) { diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/ResolveType.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/ResolveType.php index e7e58c5dabddf..12e50533f062f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/ResolveType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/ResolveType.php @@ -6,7 +6,7 @@ namespace Magento\Framework\GraphQl\Type\Output\ElementMapper\Formatter; -use GraphQL\Type\Definition\OutputType; +use Magento\Framework\GraphQl\Type\Definition\OutputType; use Magento\Framework\GraphQl\Config\Data\StructureInterface; use Magento\Framework\GraphQl\Type\Output\ElementMapper\FormatterInterface; use Magento\Framework\ObjectManagerInterface; @@ -33,7 +33,7 @@ public function __construct(ObjectManagerInterface $objectManager) /** * {@inheritDoc} */ - public function format(StructureInterface $typeStructure, OutputType $outputType) + public function format(StructureInterface $typeStructure, OutputType $outputType) : array { $config = []; if ($typeStructure instanceof InterfaceType) { diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterComposite.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterComposite.php index 0df8175b5fee4..30afcdccb6124 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterComposite.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterComposite.php @@ -6,7 +6,7 @@ namespace Magento\Framework\GraphQl\Type\Output\ElementMapper; -use GraphQL\Type\Definition\OutputType; +use Magento\Framework\GraphQl\Type\Definition\OutputType; use Magento\Framework\GraphQl\Config\Data\StructureInterface; /** @@ -30,7 +30,7 @@ public function __construct(array $formatters) /** * {@inheritDoc} */ - public function format(StructureInterface $typeStructure, OutputType $outputType) + public function format(StructureInterface $typeStructure, OutputType $outputType) : array { $config = [ 'name' => $typeStructure->getName(), diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterInterface.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterInterface.php index f92bf1876c2fb..45bc5c8c8c970 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterInterface.php @@ -7,7 +7,7 @@ namespace Magento\Framework\GraphQl\Type\Output\ElementMapper; use Magento\Framework\GraphQl\Config\Data\StructureInterface; -use GraphQL\Type\Definition\OutputType; +use Magento\Framework\GraphQl\Type\Definition\OutputType; /** * Formats particular elements of a passed in type structure to corresponding array structure. @@ -21,5 +21,5 @@ interface FormatterInterface * @param OutputType $outputType * @return array */ - public function format(StructureInterface $typeStructure, OutputType $outputType); + public function format(StructureInterface $typeStructure, OutputType $outputType) : array; } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputFactory.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputFactory.php index a886922ec44f9..e3772dea35bd7 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputFactory.php @@ -8,7 +8,7 @@ use Magento\Framework\ObjectManagerInterface; use Magento\Framework\GraphQl\Config\Data\StructureInterface; -use GraphQL\Type\Definition\OutputType; +use Magento\Framework\GraphQl\Type\Definition\OutputType; /** * Creates various output types based on structure's metadata. diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputInterfaceObject.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputInterfaceObject.php index f8c19ba97892a..6ec6b81d0e8b6 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputInterfaceObject.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputInterfaceObject.php @@ -6,7 +6,7 @@ namespace Magento\Framework\GraphQl\Type\Output; -use GraphQL\Type\Definition\InterfaceType; +use Magento\Framework\GraphQl\Type\Definition\InterfaceType; use Magento\Framework\GraphQl\Config\Data\InterfaceType as InterfaceTypeStructure; /** diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php index 94823c1630793..f62b3a6bcdc1c 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php @@ -7,7 +7,7 @@ namespace Magento\Framework\GraphQl\Type\Output; use Magento\Framework\GraphQl\Config\ConfigInterface; -use GraphQL\Type\Definition\OutputType; +use Magento\Framework\GraphQl\Type\Definition\OutputType; use Magento\Framework\GraphQl\TypeFactory; /** @@ -53,7 +53,7 @@ public function __construct( */ public function getTypeObject(string $type) : OutputType { - $instance = $this->typeFactory->createScalar($type); + $instance = $this->typeFactory->getScalar($type); if (!$instance) { $configElement = $this->config->getTypeStructure($type); $instance = $this->outputFactory->create($configElement); @@ -67,9 +67,9 @@ public function getTypeObject(string $type) : OutputType * @param string $type * @return OutputInterfaceObject|null */ - public function getInterface(string $type) : OutputInterfaceObject + public function getInterface(string $type) : ?OutputInterfaceObject { - $instance = $this->typeFactory->createScalar($type); + $instance = $this->typeFactory->getScalar($type); if (!$instance) { $configElement = $this->config->getTypeStructure($type); $instance = $this->outputFactory->create($configElement); diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputTypeObject.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputTypeObject.php index 33ae50e30ed1a..cc357c961f726 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputTypeObject.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputTypeObject.php @@ -6,7 +6,7 @@ namespace Magento\Framework\GraphQl\Type\Output; -use GraphQL\Type\Definition\ObjectType; +use Magento\Framework\GraphQl\Type\Definition\ObjectType; use Magento\Framework\GraphQl\Config\Data\Type as TypeStructure; /** diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Schema.php b/lib/internal/Magento/Framework/GraphQl/Type/Schema.php index 46703698966f8..d46bfc6910ae0 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Schema.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Schema.php @@ -11,5 +11,41 @@ */ class Schema extends \GraphQL\Type\Schema { + /** + * @api + * @param array|\GraphQL\Type\SchemaConfig $config + */ + public function __construct($config) + { + $config = $this->replaceScalarTypes($config); + parent::__construct($config); + } + private function replaceScalarTypes($config) : array + { + $recur = function (&$value) use (&$recur) { + if ($value instanceof \GraphQL\Type\Definition\ObjectType) { + /** @var \Magento\Framework\GraphQl\Type\Definition\ObjectType $value */ + $fields = $value->getFields(); + array_walk_recursive($fields, $recur); + } elseif ($value instanceof \Graphql\Type\Definition\FieldDefinition) { + /** @var \Graphql\Type\Definition\FieldDefinition $value */ + if ($value->config['type'] instanceof \Magento\Framework\GraphQl\Type\Definition\StringType) { + $value->config['type'] = \GraphQL\Type\Definition\Type::string(); + } elseif ($value->config['type'] instanceof \Magento\Framework\GraphQl\Type\Definition\IDType) { + $value->config['type'] = \GraphQL\Type\Definition\Type::id(); + } elseif ($value->config['type'] instanceof \Magento\Framework\GraphQl\Type\Definition\FloatType) { + $value->config['type'] = \GraphQL\Type\Definition\Type::float(); + } elseif ($value->config['type'] instanceof \Magento\Framework\GraphQl\Type\Definition\IntType) { + $value->config['type'] = \GraphQL\Type\Definition\Type::int(); + } elseif ($value->config['type'] instanceof \Magento\Framework\GraphQl\Type\Definition\BooleanType) { + $value->config['type'] = \GraphQL\Type\Definition\Type::boolean(); + } + } + }; + + array_walk_recursive($config, $recur); + + return $config; + } } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/SchemaFactory.php b/lib/internal/Magento/Framework/GraphQl/Type/SchemaFactory.php index 6ef60b56f8af2..06f4dba2da1c0 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/SchemaFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/SchemaFactory.php @@ -16,7 +16,7 @@ class SchemaFactory * @param array $config * @return Schema */ - public function create($config) + public function create($config) : Schema { return new Schema($config); } diff --git a/lib/internal/Magento/Framework/GraphQl/TypeFactory.php b/lib/internal/Magento/Framework/GraphQl/TypeFactory.php index 60cd69e0a4e62..719568d44905e 100644 --- a/lib/internal/Magento/Framework/GraphQl/TypeFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/TypeFactory.php @@ -13,7 +13,7 @@ use Magento\Framework\GraphQl\Type\Definition\ListOfType; use Magento\Framework\GraphQl\Type\Definition\NonNull; use Magento\Framework\GraphQl\Type\Definition\TypeInterface; -use GraphQL\Type\Definition\Type; +use Magento\Framework\GraphQl\Type\Definition\ScalarTypes; /** * Factory for @see TypeInterface implementations @@ -21,65 +21,95 @@ class TypeFactory { /** + * @var ScalarTypes + */ + private $scalarTypes; + + /** + * TypeFactory constructor. + * @param ScalarTypes $scalarTypes + */ + public function __construct(ScalarTypes $scalarTypes) + { + $this->scalarTypes = $scalarTypes; + } + + /** + * Get instance of a scalar type as singleton + * * @param string $type - * @return Type|null + * @return TypeInterface|null */ - public function createScalar(string $type) + public function getScalar(string $type) : ?TypeInterface { - $scalarTypes = Type::getInternalTypes(); - return isset($scalarTypes[$type]) ? $scalarTypes[$type] : null; + if ($this->scalarTypes->hasScalarTypeClass($type)) { + return $this->scalarTypes->getScalarTypeInstance($type); + } + return null; } /** + * Create an object type + * * @param array $config - * @return TypeInterface + * @return ObjectType */ - public function createObject(array $config) + public function createObject(array $config) : ObjectType { return new ObjectType($config); } /** + * Create an interface type + * * @param array $config - * @return TypeInterface + * @return InterfaceType */ - public function createInterface(array $config) + public function createInterface(array $config) : InterfaceType { return new InterfaceType($config); } /** + * Create an input object type + * * @param array $config - * @return TypeInterface + * @return InputObjectType */ - public function createInputObject(array $config) + public function createInputObject(array $config) : InputObjectType { return new InputObjectType($config); } /** + * Create an enum object type + * * @param array $config - * @return TypeInterface + * @return EnumType */ - public function createEnum(array $config) + public function createEnum(array $config) : EnumType { return new EnumType($config); } /** - * @param TypeInterface|Type $definedType - * @return TypeInterface + * Create an list array type + * + * @param TypeInterface $definedType + * @return ListOfType */ - public function createList(Type $definedType) + public function createList(TypeInterface $definedType) : ListOfType { return new ListOfType($definedType); } /** - * @param TypeInterface|Type $definedType - * @return TypeInterface + * Create a non null type + * + * @param TypeInterface $definedType + * @return NonNull */ - public function createNonNull(Type $definedType) + public function createNonNull(TypeInterface $definedType) : NonNull { return new NonNull($definedType); } From bf7d6b7d79cf96de0ce582ca8d873d12139852a8 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Mon, 12 Mar 2018 10:02:46 -0500 Subject: [PATCH 044/668] MAGETWO-88926: Add per-field resolution --- .../Model/Resolver/Products.php | 7 +-- .../Products/FilterArgument/AstConverter.php | 5 +- .../Products/FilterArgument/ValueParser.php | 2 +- app/code/Magento/CatalogGraphQl/etc/di.xml | 1 + app/registration.php | 28 ++++++++++ .../Argument/AstConverterInterface.php | 21 ++++++++ .../ArgumentApplier/CurrentPage.php | 8 +-- .../SearchCriteria/ArgumentApplier/Filter.php | 26 ++++++---- .../ArgumentApplier/PageSize.php | 8 +-- .../SearchCriteria/ArgumentApplier/Search.php | 4 +- .../SearchCriteria/ArgumentApplier/Sort.php | 10 ++-- .../ArgumentApplierInterface.php | 4 +- .../Argument/SearchCriteria/Builder.php | 6 +-- .../SearchCriteria/FilterGroupFactory.php | 6 +-- .../GraphQl/Resolver/ResolverInterface.php | 28 ++++++++++ .../Output/ElementMapper/Formatter/Fields.php | 52 ++++--------------- 16 files changed, 135 insertions(+), 81 deletions(-) create mode 100644 app/registration.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Argument/AstConverterInterface.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php index 4b0712f48cd8e..0778e164731de 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php @@ -6,8 +6,9 @@ namespace Magento\CatalogGraphQl\Model\Resolver; -use Magento\GraphQl\Model\ResolverContextInterface; -use Magento\GraphQl\Model\ResolverInterface; +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\Framework\GraphQl\Argument\SearchCriteria\Builder; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Filter; @@ -51,7 +52,7 @@ public function __construct( /** * {@inheritdoc} */ - public function resolve(array $args, ResolverContextInterface $context) + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) { $searchCriteria = $this->searchCriteriaBuilder->build($args); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php index 298119dd2f5fa..bcc8db4b69d6c 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php @@ -5,6 +5,7 @@ */ namespace Magento\CatalogGraphQl\Model\Resolver\Products\FilterArgument; +use Magento\Framework\GraphQl\Argument\AstConverterInterface; use Magento\Framework\GraphQl\Config\ConfigInterface; use Magento\Framework\GraphQl\Config\Data\Type; use Magento\GraphQl\Model\EntityAttributeList; @@ -18,7 +19,7 @@ /** * Converts the input value for "find" to a @see Connective format */ -class AstConverter +class AstConverter implements AstConverterInterface { /** * @var ClauseFactory @@ -140,7 +141,7 @@ private function getCatalogProductFields() * @param array $arguments * @return Connective */ - public function getFilterFromAst(string $entityType, $arguments) + public function convert(string $entityType, $arguments) { $filters = $this->getClausesFromAst( $this->referenceTypeFactory->create($entityType), diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/ValueParser.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/ValueParser.php index 7ba76851cd81a..da6fc99b378c0 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/ValueParser.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/ValueParser.php @@ -36,7 +36,7 @@ public function __construct( */ public function parse($value) { - $filters = $this->clauseConverter->getFilterFromAst(\Magento\Catalog\Model\Product::ENTITY, $value); + $filters = $this->clauseConverter->convert(\Magento\Catalog\Model\Product::ENTITY, $value); return $this->filterArgumentValueFactory->create($filters); } } diff --git a/app/code/Magento/CatalogGraphQl/etc/di.xml b/app/code/Magento/CatalogGraphQl/etc/di.xml index 5de68c235ac23..b7338139e5b9f 100644 --- a/app/code/Magento/CatalogGraphQl/etc/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/di.xml @@ -7,6 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface" type="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterComposite" /> + <preference for="Magento\Framework\GraphQl\Argument\AstConverterInterface" type="Magento\CatalogGraphQl\Model\Resolver\Products\FilterArgument\AstConverter" /> <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product"> <arguments> <argument name="collectionProcessor" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor</argument> diff --git a/app/registration.php b/app/registration.php new file mode 100644 index 0000000000000..b06a7ad74dd50 --- /dev/null +++ b/app/registration.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +//Register components (via a list of glob patterns) +namespace Magento\NonComposerComponentRegistration; +use RuntimeException; +/** + * Include files from a list of glob patterns + * + * @throws RuntimeException + * @return void + */ +function main() +{ + $globPatterns = require __DIR__ . '/etc/registration_globlist.php'; + $baseDir = dirname(__DIR__) . '/'; + foreach ($globPatterns as $globPattern) { + // Sorting is disabled intentionally for performance improvement + $files = glob($baseDir . $globPattern, GLOB_NOSORT); + if ($files === false) { + throw new RuntimeException("glob(): error with '$baseDir$globPattern'"); + } + array_map(function ($file) { require_once $file; }, $files); + } +} +main(); diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/AstConverterInterface.php b/lib/internal/Magento/Framework/GraphQl/Argument/AstConverterInterface.php new file mode 100644 index 0000000000000..21a945593bda1 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Argument/AstConverterInterface.php @@ -0,0 +1,21 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Framework\GraphQl\Argument; + +use Magento\Framework\GraphQl\Argument\Filter\Connective; + +interface AstConverterInterface +{ + /** + * Get a connective filter from an AST input + * + * @param string $entityType + * @param array $arguments + * @return Connective + */ + public function convert(string $entityType, $arguments); +} \ No newline at end of file diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/CurrentPage.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/CurrentPage.php index 11c50251c7cde..cb248b18d66f3 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/CurrentPage.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/CurrentPage.php @@ -21,13 +21,13 @@ class CurrentPage implements ArgumentApplierInterface /** * {@inheritdoc} */ - public function applyArgument(SearchCriteriaInterface $searchCriteria, ArgumentInterface $argument) + public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) { - if (is_int($argument->getValue()) || is_string($argument->getValue())) { - $searchCriteria->setCurrentPage($argument->getValue()); + if (is_int($argument) || is_string($argument)) { + $searchCriteria->setCurrentPage($argument); } else { throw new \Magento\Framework\Exception\RuntimeException( - new Phrase('Argument %1 not of type Int', [$argument->getName()]) + new Phrase('Argument %1 not of type Int', [$argument]) ); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Filter.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Filter.php index e542e0bde5120..c8b05d5beccd9 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Filter.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Filter.php @@ -6,7 +6,7 @@ namespace Magento\Framework\GraphQl\Argument\SearchCriteria\ArgumentApplier; -use Magento\Framework\GraphQl\ArgumentInterface; +use Magento\Framework\GraphQl\Argument\AstConverterInterface; use Magento\Framework\Api\Search\SearchCriteriaInterface; use Magento\Framework\GraphQl\Argument\Filter\FilterArgumentValueInterface; use Magento\Framework\App\ObjectManager; @@ -27,22 +27,30 @@ class Filter implements ArgumentApplierInterface private $filterGroupFactory; /** - * @param FilterGroupFactory|null $filterGroupFactory + * @var AstConverterInterface */ - public function __construct($filterGroupFactory = null) + private $astConverter; + + /** + * @param AstConverterInterface $astConverter + * @param FilterGroupFactory $filterGroupFactory + */ + public function __construct(AstConverterInterface $astConverter, FilterGroupFactory $filterGroupFactory) { - $this->filterGroupFactory = $filterGroupFactory ?: ObjectManager::getInstance() - ->get(FilterGroupFactory::class); + $this->astConverter = $astConverter; + $this->filterGroupFactory = $filterGroupFactory; } /** * {@inheritdoc} */ - public function applyArgument(SearchCriteriaInterface $searchCriteria, ArgumentInterface $argument) + public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) { - $filter = $argument->getValue(); - if ($filter instanceof FilterArgumentValueInterface) { - $searchCriteria->setFilterGroups($this->filterGroupFactory->create($filter)); + $filters = $this->astConverter->convert(\Magento\Catalog\Model\Product::ENTITY, $argument); + if (!empty($filters)) { + $filterGroups = $searchCriteria->getFilterGroups(); + $filterGroups = array_merge($filterGroups, $this->filterGroupFactory->create($filters)); + $searchCriteria->setFilterGroups($filterGroups); } else { throw new \Magento\Framework\Exception\RuntimeException( new Phrase('Argument %1 not of type %2', [$argument->getName(), FilterArgumentValueInterface::class]) diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/PageSize.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/PageSize.php index 71b27f2754678..641d91e5dcccd 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/PageSize.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/PageSize.php @@ -21,13 +21,13 @@ class PageSize implements ArgumentApplierInterface /** * {@inheritdoc} */ - public function applyArgument(SearchCriteriaInterface $searchCriteria, ArgumentInterface $argument) + public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) { - if (is_int($argument->getValue()) || is_string($argument->getValue())) { - $searchCriteria->setPageSize($argument->getValue()); + if (is_int($argument) || is_string($argument)) { + $searchCriteria->setPageSize($argument); } else { throw new \Magento\Framework\Exception\RuntimeException( - new Phrase('Argument %1 not of type Int', [$argument->getName()]) + new Phrase('Argument %1 not of type Int', [$argument]) ); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Search.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Search.php index 2264adc2bd9ef..233940de5af09 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Search.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Search.php @@ -39,9 +39,9 @@ public function __construct(FilterBuilder $filterBuilder, FilterGroupBuilder $fi /** * {@inheritDoc} */ - public function applyArgument(SearchCriteriaInterface $searchCriteria, ArgumentInterface $argument) + public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) { - $searchTerm = $argument->getValue(); + $searchTerm = $argument; $searchTermFilter = $this->filterBuilder->setField('search_term')->setValue($searchTerm)->create(); $this->filterGroupBuilder->addFilter($searchTermFilter); $filterGroups = $searchCriteria->getFilterGroups(); diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php index ecd7a49980d94..d8c4e4bc63d0c 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php @@ -36,20 +36,20 @@ public function __construct($sortOrderBuilder = null) /** * {@inheritdoc} */ - public function applyArgument(SearchCriteriaInterface $searchCriteria, ArgumentInterface $argument) + public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) { - if (is_array($argument->getValue())) { + if (is_array($argument)) { $sortOrders = []; - foreach ($argument->getValue() as $fieldName => $fieldValue) { + foreach ($argument as $fieldName => $fieldValue) { /** @var SortOrder $sortOrder */ $sortOrders[] = $this->sortOrderBuilder->setField($fieldName) ->setDirection($fieldValue == 'DESC' ? SortOrder::SORT_DESC : SortOrder::SORT_ASC) ->create(); } $searchCriteria->setSortOrders($sortOrders); - } elseif (!empty($argument->getValue())) { + } elseif (!empty($argument)) { throw new \Magento\Framework\Exception\RuntimeException( - new Phrase('Argument %1 not of type array or null', [$argument->getName()]) + new Phrase('Argument %1 not of type array or null', [$argument]) ); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierInterface.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierInterface.php index d404afc179fa1..88be790d1e8ee 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierInterface.php @@ -18,8 +18,8 @@ interface ArgumentApplierInterface * Apply a specific argument to a search criteria like filter, currentPage, etc. * * @param SearchCriteriaInterface $searchCriteria - * @param ArgumentInterface $argument + * @param mixed $argument * @return SearchCriteriaInterface */ - public function applyArgument(SearchCriteriaInterface $searchCriteria, ArgumentInterface $argument); + public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument); } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/Builder.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/Builder.php index e5add9a7bba20..1c35d1bdd95ae 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/Builder.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/Builder.php @@ -37,14 +37,14 @@ public function __construct( /** * Build a search criteria and apply arguments to it as filters * - * @param ArgumentInterface[] $arguments + * @param array $arguments * @return SearchCriteriaInterface */ public function build(array $arguments) { $searchCriteria = $this->searchCriteriaFactory->create(); - foreach ($arguments as $argument) { - $argumentApplier = $this->argumentApplierFactory->create($argument->getName()); + foreach ($arguments as $argumentName => $argument) { + $argumentApplier = $this->argumentApplierFactory->create($argumentName); $argumentApplier->applyArgument($searchCriteria, $argument); } return $searchCriteria; diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/FilterGroupFactory.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/FilterGroupFactory.php index 00ae30a4e675e..6b9ea5090c89f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/FilterGroupFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/FilterGroupFactory.php @@ -41,13 +41,13 @@ public function __construct( /** * Create a filter groups from an AST * - * @param FilterArgumentValueInterface $arguments + * @param Connective $arguments * @return \Magento\Framework\Api\Search\FilterGroup[] * @throws GraphQlInputException */ - public function create($arguments) + public function create(Connective $arguments) { - $filters = $arguments->getValue(); + $filters = $arguments; /** @var \Magento\Framework\Api\Search\FilterGroup[] $searchCriteriaFilterGroups */ $searchCriteriaFilterGroups = []; diff --git a/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php b/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php new file mode 100644 index 0000000000000..7c5b74fa52378 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Framework\GraphQl\Resolver; + +use Magento\Framework\GraphQl\Config\Data\Field; +use GraphQL\Type\Definition\ResolveInfo; + +/** + * Fetches data and formats it in the expected GraphQL Structure described in schema configuration. + */ +interface ResolverInterface +{ + /** + * Fetch data from persistence models and format it to requested response type structure. + * + * @param Field $field + * @param array|null $value + * @param array|null $args + * @param $context + * @param ResolveInfo $info + * @return mixed + */ + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info); +} diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php index 72d94b3c33db3..77687195ed557 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php @@ -9,6 +9,7 @@ use GraphQL\Type\Definition\OutputType; use Magento\Framework\GraphQl\ArgumentFactory; use Magento\Framework\GraphQl\Config\Data\StructureInterface; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\Framework\GraphQl\Type\Input\InputMapper; use Magento\Framework\GraphQl\Type\Output\ElementMapper\FormatterInterface; use Magento\Framework\GraphQl\Type\Output\OutputMapper; @@ -84,44 +85,25 @@ public function __construct( public function format(StructureInterface $typeStructure, OutputType $outputType) { $config = []; + /** @var Field $field */ foreach ($typeStructure->getFields() as $field) { $type = $this->getFieldType($typeStructure, $field, $outputType); $config['fields'][$field->getName()] = [ 'name' => $field->getName(), 'type' => $type, ]; + + if (!empty($field->getDescription())) { + $config['fields'][$field->getName()]['description'] = $field->getDescription(); + } + if ($field->getResolver() != null) { - /** @var \Magento\GraphQl\Model\ResolverInterface $resolver */ + /** @var ResolverInterface $resolver */ $resolver = $this->objectManager->get($field->getResolver()); $config['fields'][$field->getName()]['resolve'] = function ($value, $args, $context, $info) use ($resolver, $field) { - $infoData = []; - foreach ($info->fieldNodes as $item) { - $infoData[] = $item->toArray(true); - } - $this->clearInfo($infoData); - - $fieldArguments = []; - $declaredArguments = $this->fieldConfig->getFieldConfig($field->getName(), $args); - - foreach ($declaredArguments as $argumentName => $declaredArgument) { - $argumentValue = isset($args[$argumentName]) - ? $args[$argumentName] - : $declaredArgument->getDefaultValue(); - if ($declaredArgument->getValueParser() && $argumentValue !== null) { - $argumentValue = $declaredArgument->getValueParser()->parse($argumentValue); - } - - if ($argumentValue !== null) { - $fieldArguments[$argumentName] = $this->argumentFactory->create( - $argumentName, - $argumentValue - ); - } - } - - return $resolver->resolve($fieldArguments, $context); + return $resolver->resolve($field, $value, $args, $context, $info); }; } $config = $this->formatArguments($field, $config); @@ -199,20 +181,4 @@ private function formatArguments(Field $field, array $config) return $config; } - - /** - * Clear superfluous information from request array. - * - * @param array $data - * @return void - */ - private function clearInfo(array &$data) - { - unset($data['loc']); - foreach ($data as &$value) { - if (is_array($value)) { - $this->clearInfo($value); - } - } - } } From 374750e52039361e7d2860c554dd51d6ec62fa49 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Mon, 5 Mar 2018 10:26:55 -0600 Subject: [PATCH 045/668] MAGETWO-88934: Add default value to config --- app/code/Magento/GraphQl/etc/graphql.xsd | 1 + .../GraphQl/Config/Data/Argument.php | 38 ++++++++++++++----- .../GraphQl/Config/Data/DataFactory.php | 9 +++-- .../GraphQl/Type/Input/InputMapper.php | 34 +++++++++++++++-- 4 files changed, 64 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/GraphQl/etc/graphql.xsd b/app/code/Magento/GraphQl/etc/graphql.xsd index ad36513328d30..6683574178136 100644 --- a/app/code/Magento/GraphQl/etc/graphql.xsd +++ b/app/code/Magento/GraphQl/etc/graphql.xsd @@ -196,6 +196,7 @@ <xs:complexContent> <xs:extension base="AbstractArgument"> <xs:attribute type="GraphQlScalarTypesEnum" name="type" use="required"/> + <xs:attribute type="xs:string" name="default" default=""/> </xs:extension> </xs:complexContent> </xs:complexType> diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php index 3d4a95005ece9..67b1ae058d198 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php @@ -26,53 +26,61 @@ class Argument /** * @var string */ - private $baseType; + private $description; /** * @var string */ - private $itemType; + private $baseType; /** - * @var string + * @var bool */ - private $description; + private $required; /** * @var bool */ - private $required; + private $isList; /** * @var bool */ private $itemsRequired; + /** + * @var string|null + */ + private $default; + /** * @param string $name * @param string $type * @param string $baseType - * @param string $itemType * @param string $description * @param bool $required + * @param bool $isList * @param bool $itemsRequired + * @param string $default */ public function __construct( string $name, string $type, string $baseType, - string $itemType, string $description, bool $required, - bool $itemsRequired = false + bool $isList, + bool $itemsRequired = false, + string $default = null ) { $this->name = $name; $this->type = $type; $this->baseType = $baseType; - $this->itemType = $itemType; $this->description = $description; $this->required = $required; + $this->isList = $isList; $this->itemsRequired = $itemsRequired; + $this->default = $default; } /** @@ -122,7 +130,7 @@ public function getItemType() : string */ public function isList() : bool { - return !empty($this->itemType); + return $this->isList; } /** @@ -154,4 +162,14 @@ public function getDescription() : string { return $this->description; } + + /** + * Return default if argument is a scalar and has a configured default. Otherwise return an empty string. + * + * @return string|null + */ + public function getDefault() //: ?string + { + return $this->default; + } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php index 3ac42a46d79ff..b8f14630ec90e 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php @@ -48,7 +48,7 @@ public function createField( 'name' => $fieldData['name'], 'type' => $fieldData['type'], 'required' => isset($fieldData['required']) ? $fieldData['required'] : false, - 'itemType' => isset($fieldData['itemType']) ? $fieldData['itemType'] : "", + 'isList' => isset($fieldData['itemType']), 'resolver' => isset($fieldData['resolver']) ? $fieldData['resolver'] : "", 'description' => isset($fieldData['description']) ? $fieldData['description'] : "", 'arguments' => $arguments @@ -72,12 +72,13 @@ public function createArgument( Argument::class, [ 'name' => $argumentData['name'], - 'type' => $argumentData['type'], + 'type' => isset($argumentData['itemType']) ? $argumentData['itemType'] : $argumentData['type'], 'baseType' => isset($argumentData['baseType']) ? $argumentData['baseType'] : "", - 'itemType' => isset($argumentData['itemType']) ? $argumentData['itemType'] : "", 'description' => isset($argumentData['description']) ? $argumentData['description'] : "", 'required' => isset($argumentData['required']) ? $argumentData['required'] : false, - 'itemsRequired' => isset($argumentData['itemsRequired']) ? $argumentData['itemsRequired'] : false + 'isList' => isset($argumentData['itemType']), + 'itemsRequired' => isset($argumentData['itemsRequired']) ? $argumentData['itemsRequired'] : false, + 'default' => isset($argumentData['default']) ? $argumentData['default'] : null ] ); } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php index ff9004f2332a5..41fe789ee7ba9 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php @@ -47,24 +47,36 @@ public function __construct( } /** + * Determine an arguments type and structure for schema generation. + * * @param Argument $argument - * @return InputType + * @return array */ - public function getRepresentation(Argument $argument) : InputType + public function getRepresentation(Argument $argument) : array { $type = $argument->isList() ? $argument->getItemType() : $argument->getType(); $instance = $this->typeFactory->createScalar($type); + $calculateDefault = true; if (!$instance) { $configElement = $this->config->getTypeStructure($type); $instance = $this->inputFactory->create($configElement); + $calculateDefault = false; } + if ($argument->isList()) { $instance = $argument->areItemsRequired() ? $this->typeFactory->createNonNull($instance) : $instance; $instance = $this->typeFactory->createList($instance); } - $instance = $argument->isRequired() ? $this->typeFactory->createNonNull($instance) : $instance; + $calculatedArgument = [ + 'type' => $argument->isRequired() ? $this->typeFactory->createNonNull($instance) : $instance, + 'description' => $argument->getDescription() + ]; - return $instance; + if ($calculateDefault && $argument->getDefault() !== null) { + $calculatedArgument['defaultValue'] = $this->calculateDefaultValue($argument); + } + + return $calculatedArgument; } public function getFieldRepresentation(string $type) : InputType @@ -76,4 +88,18 @@ public function getFieldRepresentation(string $type) : InputType } return $instance; } + + private function calculateDefaultValue(Argument $argument) + { + switch ($argument->getType()) { + case 'Int': + return (int)$argument->getDefault(); + case 'Float': + return (float)$argument->getDefault(); + case 'Boolean': + return (bool)$argument->getDefault(); + default: + return $argument->getDefault(); + } + } } From ebca208017b6ddbe8524fcaf6b920bf6c0befe85 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Mon, 12 Mar 2018 11:04:54 -0500 Subject: [PATCH 046/668] MAGETWO-88934: Remove itemType and resolve getType to non-list types --- .../Magento/CatalogGraphQl/etc/graphql.xml | 4 +-- .../Converter/Type/Formatter/Fields.php | 2 +- .../GraphQl/Config/Data/Argument.php | 10 ------- .../Framework/GraphQl/Config/Data/Field.php | 26 ++++++------------- .../GraphQl/Type/Input/InputMapper.php | 2 +- .../GraphQl/Type/Input/InputObjectType.php | 2 -- .../Output/ElementMapper/Formatter/Fields.php | 2 -- 7 files changed, 12 insertions(+), 36 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql.xml b/app/code/Magento/CatalogGraphQl/etc/graphql.xml index 6e5abe697a101..bee66ec84c178 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql.xml @@ -8,8 +8,8 @@ <field xsi:type="ObjectOutputField" name="products" type="Products" resolver="Magento\CatalogGraphQl\Model\Resolver\Products"> <argument xsi:type="ScalarArgument" name="search" type="String" description="Text to be used in a full text search. If multiple keywords are specified, each keyword is evaluated separately."/> <argument xsi:type="ObjectArgument" name="filter" type="ProductFilterInput" description="Defines which search criteria to use to find the desired results. Each filter defines the field or fields to be searched, the condition type, and the search value."/> - <argument xsi:type="ScalarArgument" name="pageSize" type="Int" description="The maximum number of items to return. If no value is specified, the search returns 20 items."/> - <argument xsi:type="ScalarArgument" name="currentPage" type="Int" description="Specifies which page of results to return. If no value is specified, the first page is returned. If you specify a value that is greater than the number of available pages, an error is returned."/> + <argument xsi:type="ScalarArgument" name="pageSize" type="Int" default="20" description="The maximum number of items to return. If no value is specified, the search returns 20 items."/> + <argument xsi:type="ScalarArgument" name="currentPage" type="Int" default="0" description="Specifies which page of results to return. If no value is specified, the first page is returned. If you specify a value that is greater than the number of available pages, an error is returned."/> <argument xsi:type="ObjectArgument" name="sort" type="ProductSortInput" description="Specifies which field or fields to use for sorting the results. If you specify more than one field, Magento sorts by the first field listed. Then, if any items have the same value, those items will be sorted by the secondary field. The value for each field can be set to either ASC (ascending) or DESC (descending)."/> </field> </type> diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Fields.php index 313a24798374f..4b4204ef662fc 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Fields.php @@ -65,7 +65,7 @@ public function format(array $entry): array foreach ($entry['field'] as $field) { $fields['fields'][$field['name']] = [ 'name' => $field['name'], - 'type' => $field['type'] + 'type' => isset($field['itemType']) ? $field['itemType'] : $field['type'] ]; $fields['fields'][$field['name']] = array_merge( $fields['fields'][$field['name']], diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php index 67b1ae058d198..21033cc3bfcfe 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php @@ -113,16 +113,6 @@ public function getBaseType() : string return $this->baseType; } - /** - * Get the item type if the argument is a list of input items. - * - * @return string - */ - public function getItemType() : string - { - return $this->itemType; - } - /** * Return true if argument is a list of input items, otherwise false if it is a single object/scalar. * diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php index fc46eeaeb5582..cd8081ab86a6c 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php @@ -32,9 +32,9 @@ class Field private $required; /** - * @var string + * @var bool */ - private $itemType; + private $isList; /** * @var string @@ -49,16 +49,16 @@ class Field * @param string $name * @param string $type * @param bool $required - * @param string|null $itemType - * @param string|null $resolver - * @param string|null $description + * @param bool $isList + * @param string $resolver + * @param string $description * @param array $arguments */ public function __construct( string $name, string $type, bool $required, - string $itemType = "", + bool $isList, string $resolver = "", string $description = "", array $arguments = [] @@ -66,7 +66,7 @@ public function __construct( $this->name = $name; $this->type = $type; $this->required = $required; - $this->itemType = $itemType; + $this->isList = $isList; $this->resolver = $resolver; $this->description = $description; $this->arguments = $arguments; @@ -92,16 +92,6 @@ public function getType() : string return $this->type; } - /** - * Get the item type of if the field is a list of items. Returns empty string otherwise. - * - * @return string - */ - public function getItemType() : string - { - return $this->itemType; - } - /** * Return true if field is a list of items. False otherwise. * @@ -109,7 +99,7 @@ public function getItemType() : string */ public function isList() : bool { - return !empty($this->itemType); + return $this->isList; } /** diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php index 41fe789ee7ba9..ef4ff740e5d36 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php @@ -54,7 +54,7 @@ public function __construct( */ public function getRepresentation(Argument $argument) : array { - $type = $argument->isList() ? $argument->getItemType() : $argument->getType(); + $type = $argument->getType(); $instance = $this->typeFactory->createScalar($type); $calculateDefault = true; if (!$instance) { diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php index cc85a9e9fb752..44db23232e8c7 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php @@ -35,8 +35,6 @@ public function __construct( foreach ($structure->getFields() as $field) { if ($field->getType() == $structure->getName()) { $type = $this; - } elseif ($field->isList()) { - $type = $inputMapper->getFieldRepresentation($field->getItemType()); } else { $type = $inputMapper->getFieldRepresentation($field->getType()); } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php index 77687195ed557..fb92a8bab1ee4 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php @@ -153,8 +153,6 @@ private function getFieldType(StructureInterface $typeStructure, Field $field, O { if ($typeStructure->getName() == $field->getType()) { $type = $outputType; - } elseif ($field->isList()) { - $type = $this->outputMapper->getTypeObject($field->getItemType()); } else { $type = $this->outputMapper->getTypeObject($field->getType()); } From 6c96da4d5d4473e6cdf651b80f92a43e3b37d6f8 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Mon, 12 Mar 2018 11:32:22 -0500 Subject: [PATCH 047/668] MAGETWO-89031: Make all graphql methods to return strict type - adding strict types --- .../HttpHeaderProcessor/ContentTypeProcessor.php | 2 +- .../HttpHeaderProcessor/StoreProcessor.php | 2 +- lib/internal/Magento/Framework/GraphQl/Argument.php | 2 +- .../Magento/Framework/GraphQl/ArgumentInterface.php | 1 + .../Magento/Framework/GraphQl/Config/Config.php | 1 + .../Framework/GraphQl/Config/ConfigInterface.php | 1 + .../GraphQl/Config/Converter/Normalizer/Enum.php | 1 + .../GraphQl/Config/Converter/Normalizer/Input.php | 1 + .../GraphQl/Config/Converter/Normalizer/Output.php | 1 + .../GraphQl/Config/Converter/NormalizerComposite.php | 1 + .../GraphQl/Config/Converter/NormalizerInterface.php | 1 + .../Config/Converter/Type/Formatter/Description.php | 1 + .../Config/Converter/Type/Formatter/Fields.php | 1 + .../Config/Converter/Type/Formatter/Interfaces.php | 1 + .../Config/Converter/Type/FormatterComposite.php | 1 + .../Config/Converter/Type/FormatterInterface.php | 1 + .../Framework/GraphQl/Config/Data/Argument.php | 1 + .../Framework/GraphQl/Config/Data/DataFactory.php | 1 + .../Magento/Framework/GraphQl/Config/Data/Enum.php | 1 + .../Framework/GraphQl/Config/Data/Enum/Value.php | 1 + .../Magento/Framework/GraphQl/Config/Data/Field.php | 1 + .../Framework/GraphQl/Config/Data/InterfaceType.php | 1 + .../GraphQl/Config/Data/Mapper/EnumMapper.php | 1 + .../Config/Data/Mapper/StructureMapperInterface.php | 1 + .../Config/Data/Mapper/TypeInterfaceMapper.php | 1 + .../GraphQl/Config/Data/Mapper/TypeMapper.php | 1 + .../GraphQl/Config/Data/StructureInterface.php | 1 + .../Magento/Framework/GraphQl/Config/Data/Type.php | 1 + .../Magento/Framework/GraphQl/Config/FieldConfig.php | 1 + .../Magento/Framework/GraphQl/ExceptionFormatter.php | 5 +++-- .../GraphQl/HttpHeaderProcessorInterface.php | 4 +++- .../Framework/GraphQl/HttpRequestProcessor.php | 4 +++- lib/internal/Magento/Framework/GraphQl/Promise.php | 1 + .../Magento/Framework/GraphQl/Query/EnumLookup.php | 1 + .../GraphQl/Query/PostFetchProcessorInterface.php | 1 + .../Magento/Framework/GraphQl/QueryProcessor.php | 1 + .../Magento/Framework/GraphQl/SchemaProvider.php | 1 + .../GraphQl/Type/Definition/BooleanType.php | 1 + .../Framework/GraphQl/Type/Definition/EnumType.php | 1 + .../Framework/GraphQl/Type/Definition/FloatType.php | 1 + .../Framework/GraphQl/Type/Definition/IdType.php | 1 + .../GraphQl/Type/Definition/InputObjectType.php | 1 + .../Framework/GraphQl/Type/Definition/InputType.php | 1 + .../Framework/GraphQl/Type/Definition/IntType.php | 1 + .../GraphQl/Type/Definition/InterfaceType.php | 1 + .../Framework/GraphQl/Type/Definition/ListOfType.php | 1 + .../Framework/GraphQl/Type/Definition/NonNull.php | 1 + .../Framework/GraphQl/Type/Definition/ObjectType.php | 1 + .../Framework/GraphQl/Type/Definition/OutputType.php | 1 + .../GraphQl/Type/Definition/ResolveInfo.php | 1 + .../GraphQl/Type/Definition/ScalarTypes.php | 1 + .../Framework/GraphQl/Type/Definition/StringType.php | 1 + .../GraphQl/Type/Definition/TypeInterface.php | 1 + .../Framework/GraphQl/Type/Entity/DefaultMapper.php | 1 + .../GraphQl/Type/Entity/MapperInterface.php | 1 + .../GraphQl/Type/Enum/DataMapperInterface.php | 1 + .../GraphQl/Type/Enum/DefaultDataMapper.php | 1 + .../Magento/Framework/GraphQl/Type/Enum/Enum.php | 1 + .../Framework/GraphQl/Type/Input/InputFactory.php | 1 + .../Framework/GraphQl/Type/Input/InputMapper.php | 1 + .../Framework/GraphQl/Type/Input/InputObjectType.php | 1 + .../Framework/GraphQl/Type/Output/ElementMapper.php | 1 + .../Type/Output/ElementMapper/Formatter/Fields.php | 1 + .../Output/ElementMapper/Formatter/Interfaces.php | 1 + .../Output/ElementMapper/Formatter/ResolveType.php | 1 + .../Type/Output/ElementMapper/FormatterComposite.php | 1 + .../Type/Output/ElementMapper/FormatterInterface.php | 1 + .../Framework/GraphQl/Type/Output/OutputFactory.php | 1 + .../GraphQl/Type/Output/OutputInterfaceObject.php | 1 + .../Framework/GraphQl/Type/Output/OutputMapper.php | 1 + .../GraphQl/Type/Output/OutputTypeObject.php | 1 + .../Magento/Framework/GraphQl/Type/Schema.php | 12 +++++++++++- .../Magento/Framework/GraphQl/Type/SchemaFactory.php | 2 ++ .../Magento/Framework/GraphQl/TypeFactory.php | 1 + 74 files changed, 91 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php index d3255e1c0725c..a75b3e10775b7 100644 --- a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php +++ b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php @@ -20,7 +20,7 @@ class ContentTypeProcessor implements HttpHeaderProcessorInterface * {@inheritDoc} * @throws LocalizedException */ - public function processHeaderValue($headerValue) + public function processHeaderValue($headerValue) : void { if (!$headerValue || strpos($headerValue, 'application/json') === false) { throw new LocalizedException( diff --git a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php index 48d62f27d1d70..655e974b4fdf9 100644 --- a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php +++ b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php @@ -36,7 +36,7 @@ public function __construct(StoreManagerInterface $storeManager) * {@inheritDoc} * @throws NoSuchEntityException */ - public function processHeaderValue($headerValue) + public function processHeaderValue($headerValue) : void { if ($headerValue) { $storeCode = ltrim(rtrim($headerValue)); diff --git a/lib/internal/Magento/Framework/GraphQl/Argument.php b/lib/internal/Magento/Framework/GraphQl/Argument.php index 502e0ffcfa10c..09b60627ab677 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument.php @@ -31,7 +31,7 @@ public function __construct($name, $value) /** * {@inheritdoc} */ - public function getName() + public function getName() : string { return $this->name; } diff --git a/lib/internal/Magento/Framework/GraphQl/ArgumentInterface.php b/lib/internal/Magento/Framework/GraphQl/ArgumentInterface.php index 9ff8d3a33175b..9f67c75428ed5 100644 --- a/lib/internal/Magento/Framework/GraphQl/ArgumentInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/ArgumentInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Framework\GraphQl; use Magento\Framework\GraphQl\Argument\ArgumentValueInterface; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Config.php b/lib/internal/Magento/Framework/GraphQl/Config/Config.php index 98eeef2fe7957..9ed29558240ea 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Config.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Config.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/ConfigInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/ConfigInterface.php index 48bbbe40f3442..c5f1d852ef647 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/ConfigInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/ConfigInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Enum.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Enum.php index 6e317bf194845..90f20d00c970d 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Enum.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Enum.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Converter\Normalizer; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Input.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Input.php index 25602a2179ef4..c2d690c40bcb0 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Input.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Input.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Converter\Normalizer; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Output.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Output.php index 480f6652fec56..01551b81bc0e6 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Output.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Output.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Converter\Normalizer; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerComposite.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerComposite.php index 400783b33a18e..fa45f595a7bc1 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerComposite.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerComposite.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Converter; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerInterface.php index de511ab54f6f7..203be0c6dd2b4 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Converter; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Description.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Description.php index 84eb62df0ae8c..86d845bd0f493 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Description.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Description.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Converter\Type\Formatter; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Fields.php index 313a24798374f..144dde237461f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Fields.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Converter\Type\Formatter; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Interfaces.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Interfaces.php index f2cd94e8b8a85..d465dbffbc3fd 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Interfaces.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Interfaces.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Converter\Type\Formatter; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterComposite.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterComposite.php index e82371c8131e3..0aa359c047e29 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterComposite.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterComposite.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Converter\Type; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterInterface.php index f91c92b96ce9b..14783e73faf0b 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Converter\Type; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php index 3d4a95005ece9..b6e7c8ce5846b 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Data; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php index 3ac42a46d79ff..2a4f8d1dd26f8 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Data; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Enum.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Enum.php index 4b7a24d1f4509..e28d5b54284b5 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Enum.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Enum.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Data; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Enum/Value.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Enum/Value.php index ecbfb1fd48523..0f6908ace1430 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Enum/Value.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Enum/Value.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Data\Enum; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php index fc46eeaeb5582..d2c543bc0d7d7 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Data; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/InterfaceType.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/InterfaceType.php index ee32f97a83f59..8afa13ed794c4 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/InterfaceType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/InterfaceType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Data; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/EnumMapper.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/EnumMapper.php index 891ff3f56a2c3..551e592d10710 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/EnumMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/EnumMapper.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Data\Mapper; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/StructureMapperInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/StructureMapperInterface.php index 88f1b08001764..2adf9e36a9189 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/StructureMapperInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/StructureMapperInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Data\Mapper; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/TypeInterfaceMapper.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/TypeInterfaceMapper.php index f0b026deeee06..4d77d309330c0 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/TypeInterfaceMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/TypeInterfaceMapper.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Data\Mapper; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/TypeMapper.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/TypeMapper.php index e770981ad0dc3..e079a20fe1c8f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/TypeMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/TypeMapper.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Data\Mapper; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/StructureInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/StructureInterface.php index b852b0b2cbdc5..f111adfe18b52 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/StructureInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/StructureInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Data; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Type.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Type.php index 86d00a6c70172..274c489854b45 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Type.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Type.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Data; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/FieldConfig.php b/lib/internal/Magento/Framework/GraphQl/Config/FieldConfig.php index 748d1e462dbcb..b2d028686bd6b 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/FieldConfig.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/FieldConfig.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config; diff --git a/lib/internal/Magento/Framework/GraphQl/ExceptionFormatter.php b/lib/internal/Magento/Framework/GraphQl/ExceptionFormatter.php index 02e636e82061b..3dfb634255c82 100644 --- a/lib/internal/Magento/Framework/GraphQl/ExceptionFormatter.php +++ b/lib/internal/Magento/Framework/GraphQl/ExceptionFormatter.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl; @@ -49,7 +50,7 @@ public function __construct(State $appState, ErrorProcessor $errorProcessor, Log * @return array * @throws \Throwable */ - public function create(\Throwable $exception, $internalErrorMessage = null) + public function create(\Throwable $exception, $internalErrorMessage = null) : array { if (!$this->shouldShowDetail()) { $reportId = uniqid("graph-ql-"); @@ -72,7 +73,7 @@ public function create(\Throwable $exception, $internalErrorMessage = null) * * @return bool */ - public function shouldShowDetail() + public function shouldShowDetail() : bool { return $this->appState->getMode() === State::MODE_DEVELOPER; } diff --git a/lib/internal/Magento/Framework/GraphQl/HttpHeaderProcessorInterface.php b/lib/internal/Magento/Framework/GraphQl/HttpHeaderProcessorInterface.php index 52317b329204d..5f2399de6ed20 100644 --- a/lib/internal/Magento/Framework/GraphQl/HttpHeaderProcessorInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/HttpHeaderProcessorInterface.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\Framework\GraphQl; /** @@ -19,5 +21,5 @@ interface HttpHeaderProcessorInterface * @param bool|string $headerValue * @return void */ - public function processHeaderValue($headerValue); + public function processHeaderValue($headerValue) : void; } diff --git a/lib/internal/Magento/Framework/GraphQl/HttpRequestProcessor.php b/lib/internal/Magento/Framework/GraphQl/HttpRequestProcessor.php index a2b5b08b700ca..1b36e2c8b5249 100644 --- a/lib/internal/Magento/Framework/GraphQl/HttpRequestProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/HttpRequestProcessor.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl; @@ -30,8 +31,9 @@ public function __construct(array $graphQlHeaders) * Process the headers from a request given from usually the controller * * @param Http $request + * @return void */ - public function processHeaders(Http $request) + public function processHeaders(Http $request) : void { foreach ($this->headerProcessors as $headerName => $headerClass) { $headerClass->processHeaderValue($request->getHeader($headerName)); diff --git a/lib/internal/Magento/Framework/GraphQl/Promise.php b/lib/internal/Magento/Framework/GraphQl/Promise.php index b5cb5c737f2db..c31ed5bbc2268 100644 --- a/lib/internal/Magento/Framework/GraphQl/Promise.php +++ b/lib/internal/Magento/Framework/GraphQl/Promise.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl; diff --git a/lib/internal/Magento/Framework/GraphQl/Query/EnumLookup.php b/lib/internal/Magento/Framework/GraphQl/Query/EnumLookup.php index 85559fc40d6af..b9d9fb9784183 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/EnumLookup.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/EnumLookup.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Query; diff --git a/lib/internal/Magento/Framework/GraphQl/Query/PostFetchProcessorInterface.php b/lib/internal/Magento/Framework/GraphQl/Query/PostFetchProcessorInterface.php index a41d1e676d30f..d18f9df4be28c 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/PostFetchProcessorInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/PostFetchProcessorInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Query; diff --git a/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php index 33578c25455c7..9c8ae54195fa3 100644 --- a/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl; diff --git a/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php b/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php index 6116e0b1139d6..a5343293fdd36 100644 --- a/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php +++ b/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/BooleanType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/BooleanType.php index e905af4d6bcd5..fa02b9dc5eecd 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/BooleanType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/BooleanType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/EnumType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/EnumType.php index 5063220bf8f95..307be6871da06 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/EnumType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/EnumType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/FloatType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/FloatType.php index 10fdc568ce268..ae73f674734cf 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/FloatType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/FloatType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/IdType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/IdType.php index 30a8bebdc867a..8b6a3f3d1d9f3 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/IdType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/IdType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputObjectType.php index d9c48754d10c3..bdebb87616a28 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputObjectType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputType.php index 56377dbbc02c2..5990be95a1115 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/InputType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/IntType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/IntType.php index 2e3811efe3015..8af7eb290a2cd 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/IntType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/IntType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/InterfaceType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/InterfaceType.php index 77b16228c1a3c..0979094b9c6c5 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/InterfaceType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/InterfaceType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ListOfType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ListOfType.php index e7020433e5c78..01b7ac41f5595 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ListOfType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ListOfType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/NonNull.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/NonNull.php index 8bab282b2efba..025d0318a4365 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/NonNull.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/NonNull.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ObjectType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ObjectType.php index 22d0c67754c6b..ea01d70c3f5ea 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ObjectType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/OutputType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/OutputType.php index 51760385682a8..4572bcc4f13f2 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/OutputType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/OutputType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ResolveInfo.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ResolveInfo.php index c05a2a0498b2f..1b1b86eada374 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ResolveInfo.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ResolveInfo.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php index 65c67a4daa3da..0531c4eae3387 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/StringType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/StringType.php index 6f48ce84343a5..04d245de15a01 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/StringType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/StringType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/TypeInterface.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/TypeInterface.php index 7960b04b6f622..0e8db6316850f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/TypeInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/TypeInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Definition; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Entity/DefaultMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Entity/DefaultMapper.php index 0db765ced273c..9deee4d1c2ae9 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Entity/DefaultMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Entity/DefaultMapper.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Entity; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Entity/MapperInterface.php b/lib/internal/Magento/Framework/GraphQl/Type/Entity/MapperInterface.php index b55db8bf9d68a..6c5a0cba4a9d3 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Entity/MapperInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Entity/MapperInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Entity; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Enum/DataMapperInterface.php b/lib/internal/Magento/Framework/GraphQl/Type/Enum/DataMapperInterface.php index 2f59364d7480d..1893a474bed6d 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Enum/DataMapperInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Enum/DataMapperInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Enum; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Enum/DefaultDataMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Enum/DefaultDataMapper.php index 25f084441d864..f5c461fad921b 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Enum/DefaultDataMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Enum/DefaultDataMapper.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Enum; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php b/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php index 8347aaab19c4c..c4d083a12595a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Enum; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputFactory.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputFactory.php index a8274c19cfe7b..05dabff7bd410 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputFactory.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Input; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php index 821e984db7457..ce0d3ee23f895 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Input; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php index 6e05703d5d22a..dc7cac64a99e5 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Input; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper.php index 78e43d225e968..5645d86ce0ef9 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Output; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php index 9a0e101093357..3bd5f57fa0106 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Output\ElementMapper\Formatter; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php index 9a707c44937be..9da0d2e9fac4f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Output\ElementMapper\Formatter; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/ResolveType.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/ResolveType.php index 12e50533f062f..853444dd920b9 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/ResolveType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/ResolveType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Output\ElementMapper\Formatter; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterComposite.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterComposite.php index 30afcdccb6124..4c1810868d458 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterComposite.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterComposite.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Output\ElementMapper; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterInterface.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterInterface.php index 45bc5c8c8c970..df71b875b4952 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Output\ElementMapper; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputFactory.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputFactory.php index e3772dea35bd7..bb9c4ad043ad0 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputFactory.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Output; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputInterfaceObject.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputInterfaceObject.php index 6ec6b81d0e8b6..4fea89d2c062d 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputInterfaceObject.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputInterfaceObject.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Output; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php index f62b3a6bcdc1c..a499892791e01 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Output; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputTypeObject.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputTypeObject.php index cc357c961f726..67941768527a0 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputTypeObject.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputTypeObject.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type\Output; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Schema.php b/lib/internal/Magento/Framework/GraphQl/Type/Schema.php index d46bfc6910ae0..e588f77785e8f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Schema.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Schema.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Type; @@ -21,7 +22,16 @@ public function __construct($config) parent::__construct($config); } - private function replaceScalarTypes($config) : array + /** + * Replace wrappers for scalar types with webonyx scalar types to prevent creation of two scalar types. + * + * Note that webonyx will try to inject it's own scalar types and because wrappers have the same name + * Example: String vs String - webonyx will trigger an exception. + * + * @param array $config + * @return array + */ + private function replaceScalarTypes(array $config) : array { $recur = function (&$value) use (&$recur) { if ($value instanceof \GraphQL\Type\Definition\ObjectType) { diff --git a/lib/internal/Magento/Framework/GraphQl/Type/SchemaFactory.php b/lib/internal/Magento/Framework/GraphQl/Type/SchemaFactory.php index 06f4dba2da1c0..c03b5a4604380 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/SchemaFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/SchemaFactory.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\Framework\GraphQl\Type; /** diff --git a/lib/internal/Magento/Framework/GraphQl/TypeFactory.php b/lib/internal/Magento/Framework/GraphQl/TypeFactory.php index 719568d44905e..a38a00fda463d 100644 --- a/lib/internal/Magento/Framework/GraphQl/TypeFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/TypeFactory.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl; From 5c75e54401d409d4ca0d0953f4a0c06fab5ba8c2 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Mon, 12 Mar 2018 13:06:11 -0500 Subject: [PATCH 048/668] MAGETWO-88934: Format files --- .../Framework/GraphQl/Type/Enum/Enum.php | 4 +- .../GraphQl/Type/Input/InputFactory.php | 2 +- .../GraphQl/Type/Input/InputMapper.php | 42 ++++++++++--------- .../GraphQl/Type/Input/InputObjectType.php | 1 - 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php b/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php index 8347aaab19c4c..f628db16fd028 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php @@ -9,10 +9,12 @@ use Magento\Framework\GraphQl\Type\Definition\EnumType; use Magento\Framework\GraphQl\Config\Data\Enum as EnumStructure; +/** + * Object representation of a GraphQL enum field + */ class Enum extends EnumType { /** - * Enum constructor. * @param EnumStructure $structure */ public function __construct(EnumStructure $structure) diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputFactory.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputFactory.php index a8274c19cfe7b..161bb07822638 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputFactory.php @@ -8,7 +8,7 @@ use Magento\Framework\ObjectManagerInterface; use Magento\Framework\GraphQl\Config\Data\StructureInterface; -use GraphQL\Type\Definition\InputType; +use Magento\Framework\GraphQl\Type\Definition\InputType; class InputFactory { diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php index 5fbdf94f98582..bdc45660697ac 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php @@ -8,7 +8,7 @@ use Magento\Framework\GraphQl\Config\ConfigInterface; use Magento\Framework\GraphQl\Config\Data\Argument; -use GraphQL\Type\Definition\InputType; +use Magento\Framework\GraphQl\Type\Definition\InputType; use Magento\Framework\GraphQl\TypeFactory; /** @@ -50,12 +50,12 @@ public function __construct( * Determine an arguments type and structure for schema generation. * * @param Argument $argument - * @return InputType + * @return array */ - public function getRepresentation(Argument $argument) : InputType + public function getRepresentation(Argument $argument) : array { $type = $argument->getType(); - $instance = $this->typeFactory->createScalar($type); + $instance = $this->typeFactory->getScalar($type); $calculateDefault = true; if (!$instance) { $configElement = $this->config->getTypeStructure($type); @@ -73,12 +73,30 @@ public function getRepresentation(Argument $argument) : InputType ]; if ($calculateDefault && $argument->getDefault() !== null) { - $calculatedArgument['defaultValue'] = $this->calculateDefaultValue($argument); + switch ($argument->getType()) { + case 'Int': + $calculatedArgument['defaultValue'] = (int)$argument->getDefault(); + break; + case 'Float': + $calculatedArgument['defaultValue'] = (float)$argument->getDefault(); + break; + case 'Boolean': + $calculatedArgument['defaultValue'] = (bool)$argument->getDefault(); + break; + default: + $calculatedArgument['defaultValue'] = $argument->getDefault(); + } } return $calculatedArgument; } + /** + * Return object representation of field for passed in type. + * + * @param string $type + * @return InputType + */ public function getFieldRepresentation(string $type) : InputType { $instance = $this->typeFactory->getScalar($type); @@ -88,18 +106,4 @@ public function getFieldRepresentation(string $type) : InputType } return $instance; } - - private function calculateDefaultValue(Argument $argument) - { - switch ($argument->getType()) { - case 'Int': - return (int)$argument->getDefault(); - case 'Float': - return (float)$argument->getDefault(); - case 'Boolean': - return (bool)$argument->getDefault(); - default: - return $argument->getDefault(); - } - } } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php index 9b0dd9a553956..49a721ee7fd4d 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php @@ -11,7 +11,6 @@ use Magento\Framework\GraphQl\Config\Data\Type as TypeStructure; use Magento\Framework\GraphQl\Type\Definition\TypeInterface; use Magento\Framework\GraphQl\TypeFactory; -use Magento\Framework\GraphQl\Type\Definition\NonNull; /** * Class InputObjectType From b95cde264883774d4e54387c9ca615d46d8c5500 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@magento.com> Date: Mon, 12 Mar 2018 14:43:25 -0500 Subject: [PATCH 049/668] MAGETWO-89178: Create integration or functional test - Added integration test for GraphQl controller to test dispatch --- .../TestFramework/Annotation/AppArea.php | 1 + .../Magento/TestFramework/Application.php | 1 + .../Magento/Test/Annotation/AppAreaTest.php | 3 + .../Magento/Test/ApplicationTest.php | 3 + .../Controller/GraphQlControllerTest.php | 106 ++++++++++++++++++ lib/internal/Magento/Framework/App/Area.php | 2 + 6 files changed, 116 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AppArea.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AppArea.php index 6a63a96d47849..879e771d3239d 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AppArea.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AppArea.php @@ -26,6 +26,7 @@ class AppArea \Magento\Framework\App\Area::AREA_WEBAPI_REST, \Magento\Framework\App\Area::AREA_WEBAPI_SOAP, \Magento\Framework\App\Area::AREA_CRONTAB, + \Magento\Framework\App\Area::AREA_GRAPHQL ]; /** diff --git a/dev/tests/integration/framework/Magento/TestFramework/Application.php b/dev/tests/integration/framework/Magento/TestFramework/Application.php index 29bc3de4c2441..4fec36633c9b6 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Application.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Application.php @@ -670,6 +670,7 @@ public function loadArea($areaCode) \Magento\Framework\App\Area::AREA_WEBAPI_REST, \Magento\Framework\App\Area::AREA_WEBAPI_SOAP, \Magento\Framework\App\Area::AREA_CRONTAB, + \Magento\Framework\App\Area::AREA_GRAPHQL ]; if (in_array($areaCode, $areasForPartialLoading, true)) { $app->getArea($areaCode)->load(\Magento\Framework\App\Area::PART_CONFIG); diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/AppAreaTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/AppAreaTest.php index dd361a5d0ed74..c89df3417ed71 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/AppAreaTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/AppAreaTest.php @@ -135,6 +135,9 @@ public function startTestWithDifferentAreaCodes() [ 'area_code' => Area::AREA_CRONTAB, ], + [ + 'area_code' => Area::AREA_GRAPHQL, + ], ]; } } diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/ApplicationTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/ApplicationTest.php index b203438db42bc..e0bba5bcf222c 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/ApplicationTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/ApplicationTest.php @@ -161,6 +161,9 @@ public function partialLoadAreaDataProvider() [ 'area_code' => Area::AREA_CRONTAB, ], + [ + 'area_code' => Area::AREA_GRAPHQL, + ], ]; } } diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php new file mode 100644 index 0000000000000..376e9e10797be --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php @@ -0,0 +1,106 @@ +<?php + +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\GraphQl\Controller; + +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\App\Request\Http; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\App\State; +use Magento\Framework\GraphQl\HttpHeaderProcessorInterface; +use Magento\Framework\GraphQl\HttpRequestProcessor; +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Framework\Webapi\Request; +use Magento\GraphQl\Controller\GraphQl; + +/** + * Class GraphQlTest + * + * @magentoAppArea graphql + * @magentoDataFixture Magento/Catalog/_files/product_without_options.php + */ + +class GraphQlControllerTest extends \PHPUnit\Framework\TestCase +{ + /** @var string */ + private $mageMode; + + const CONTENT_TYPE = 'application/json'; + + + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + + /** @var \Magento\Framework\App\Request\Http $request */ + private $request; + + /** + * @var GraphQl $graphql + */ + private $graphql; + + /** @var array */ + private $serverArray; + + + /** @var SerializerInterface */ + private $jsonSerializer; + + protected function setUp() + { + // parent::setUp(); + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); + $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); + } + + /** + * Tests if a graphql schema is generated and request is dispatched and response generated + */ + public function testDispatch() + { + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + + /** @var ProductInterface $product */ + $product = $productRepository->get('simple'); + + $query + = <<<QUERY + { + products(filter: {sku: {eq: "simple"}}) + { + items { + id + name + sku + } + } + } +QUERY; + $postData = [ + 'query' => $query, + 'variables'=> null, + 'operationName'=> null + ]; + /** @var Http $request */ + $request = $this->objectManager->get(\Magento\Framework\App\Request\Http::class); + $request->setPathInfo('/graphql'); + $request->setContent(json_encode($postData)); + $headers = $this->objectManager->create(\Zend\Http\Headers::class) + ->addHeaders(['Content-Type' => 'application/json'] + ); + $request->setHeaders($headers); + $response = $this->graphql->dispatch($request); + $output = $this->jsonSerializer->unserialize($response->getContent()); + $this->assertEquals($output['data']['products']['items'][0]['id'], $product->getId()); + $this->assertEquals($output['data']['products']['items'][0]['sku'], $product->getSku()); + $this->assertEquals($output['data']['products']['items'][0]['name'], $product->getName()); + } +} diff --git a/lib/internal/Magento/Framework/App/Area.php b/lib/internal/Magento/Framework/App/Area.php index 265a6554d2ddc..c1c2734b0b8aa 100644 --- a/lib/internal/Magento/Framework/App/Area.php +++ b/lib/internal/Magento/Framework/App/Area.php @@ -22,6 +22,8 @@ class Area implements \Magento\Framework\App\AreaInterface const AREA_CRONTAB = 'crontab'; const AREA_WEBAPI_REST = 'webapi_rest'; const AREA_WEBAPI_SOAP = 'webapi_soap'; + const AREA_GRAPHQL = 'graphql'; + /** * @deprecated From 38ad67a96b03a35b49f08a4411b57a6b8d61a362 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Mon, 12 Mar 2018 16:15:19 -0500 Subject: [PATCH 050/668] MAGETWO-89081: CE edition - Update composer dependencies, and fix Travis build issues - revert changes in e20d5b8f024eba4010d6d561a31100838316cccf in function tests --- .../Magento/FunctionalTest/AdminNotification/composer.json | 2 +- .../FunctionalTest/AdvancedPricingImportExport/composer.json | 2 +- .../functional/Magento/FunctionalTest/Analytics/composer.json | 2 +- .../Magento/FunctionalTest/Authorization/composer.json | 2 +- .../Magento/FunctionalTest/Authorizenet/composer.json | 2 +- .../functional/Magento/FunctionalTest/Backend/composer.json | 2 +- .../functional/Magento/FunctionalTest/Backup/composer.json | 2 +- .../functional/Magento/FunctionalTest/Braintree/composer.json | 2 +- .../functional/Magento/FunctionalTest/Bundle/composer.json | 2 +- .../Magento/FunctionalTest/BundleImportExport/composer.json | 2 +- .../Magento/FunctionalTest/CacheInvalidate/composer.json | 2 +- .../functional/Magento/FunctionalTest/Captcha/composer.json | 2 +- .../Magento/FunctionalTest/CatalogAnalytics/composer.json | 2 +- .../Magento/FunctionalTest/CatalogImportExport/composer.json | 2 +- .../Magento/FunctionalTest/CatalogInventory/composer.json | 2 +- .../functional/Magento/FunctionalTest/CatalogRule/composer.json | 2 +- .../FunctionalTest/CatalogRuleConfigurable/composer.json | 2 +- .../Magento/FunctionalTest/CatalogUrlRewrite/composer.json | 2 +- .../Magento/FunctionalTest/CatalogWidget/composer.json | 2 +- .../Magento/FunctionalTest/CheckoutAgreements/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Cms/composer.json | 2 +- .../Magento/FunctionalTest/CmsUrlRewrite/composer.json | 2 +- .../functional/Magento/FunctionalTest/Config/composer.json | 2 +- .../FunctionalTest/ConfigurableImportExport/composer.json | 2 +- .../FunctionalTest/ConfigurableProductSales/composer.json | 2 +- .../functional/Magento/FunctionalTest/Contact/composer.json | 2 +- .../functional/Magento/FunctionalTest/Cookie/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Cron/composer.json | 2 +- .../Magento/FunctionalTest/CurrencySymbol/composer.json | 2 +- .../functional/Magento/FunctionalTest/Customer/composer.json | 2 +- .../Magento/FunctionalTest/CustomerAnalytics/composer.json | 2 +- .../Magento/FunctionalTest/CustomerImportExport/composer.json | 2 +- .../functional/Magento/FunctionalTest/Deploy/composer.json | 2 +- .../functional/Magento/FunctionalTest/Developer/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Dhl/composer.json | 2 +- .../functional/Magento/FunctionalTest/Directory/composer.json | 2 +- .../Magento/FunctionalTest/Downloadable/composer.json | 2 +- .../FunctionalTest/DownloadableImportExport/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Eav/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Email/composer.json | 2 +- .../Magento/FunctionalTest/EncryptionKey/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Fedex/composer.json | 2 +- .../functional/Magento/FunctionalTest/GiftMessage/composer.json | 2 +- .../Magento/FunctionalTest/GoogleAdwords/composer.json | 2 +- .../Magento/FunctionalTest/GoogleAnalytics/composer.json | 2 +- .../Magento/FunctionalTest/GoogleOptimizer/composer.json | 2 +- .../functional/Magento/FunctionalTest/GraphQl/composer.json | 2 +- .../Magento/FunctionalTest/GroupedImportExport/composer.json | 2 +- .../Magento/FunctionalTest/GroupedProduct/composer.json | 2 +- .../Magento/FunctionalTest/ImportExport/composer.json | 2 +- .../functional/Magento/FunctionalTest/Indexer/composer.json | 2 +- .../Magento/FunctionalTest/InstantPurchase/composer.json | 2 +- .../functional/Magento/FunctionalTest/Integration/composer.json | 2 +- .../Magento/FunctionalTest/LayeredNavigation/composer.json | 2 +- .../functional/Magento/FunctionalTest/Marketplace/composer.json | 2 +- .../Magento/FunctionalTest/MediaStorage/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Msrp/composer.json | 2 +- .../Magento/FunctionalTest/Multishipping/composer.json | 2 +- .../Magento/FunctionalTest/NewRelicReporting/composer.json | 2 +- .../functional/Magento/FunctionalTest/Newsletter/composer.json | 2 +- .../Magento/FunctionalTest/OfflinePayments/composer.json | 2 +- .../Magento/FunctionalTest/OfflineShipping/composer.json | 2 +- .../functional/Magento/FunctionalTest/PageCache/composer.json | 2 +- .../functional/Magento/FunctionalTest/Payment/composer.json | 2 +- .../functional/Magento/FunctionalTest/Paypal/composer.json | 2 +- .../functional/Magento/FunctionalTest/Persistent/composer.json | 2 +- .../Magento/FunctionalTest/ProductAlert/composer.json | 2 +- .../Magento/FunctionalTest/ProductVideo/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Quote/composer.json | 2 +- .../Magento/FunctionalTest/QuoteAnalytics/composer.json | 2 +- .../functional/Magento/FunctionalTest/Reports/composer.json | 2 +- .../functional/Magento/FunctionalTest/RequireJs/composer.json | 2 +- .../functional/Magento/FunctionalTest/Review/composer.json | 2 +- .../Magento/FunctionalTest/ReviewAnalytics/composer.json | 2 +- .../functional/Magento/FunctionalTest/Robots/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Rss/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Rule/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Sales/composer.json | 2 +- .../Magento/FunctionalTest/SalesAnalytics/composer.json | 2 +- .../Magento/FunctionalTest/SalesInventory/composer.json | 2 +- .../Magento/FunctionalTest/SalesSequence/composer.json | 2 +- .../functional/Magento/FunctionalTest/SampleData/composer.json | 2 +- .../Magento/FunctionalTest/SampleTemplates/composer.json | 2 +- .../functional/Magento/FunctionalTest/SampleTests/composer.json | 2 +- .../functional/Magento/FunctionalTest/Security/composer.json | 2 +- .../functional/Magento/FunctionalTest/SendFriend/composer.json | 2 +- .../functional/Magento/FunctionalTest/Shipping/composer.json | 2 +- .../functional/Magento/FunctionalTest/Sitemap/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Store/composer.json | 2 +- .../functional/Magento/FunctionalTest/Swagger/composer.json | 2 +- .../functional/Magento/FunctionalTest/Swatches/composer.json | 2 +- .../FunctionalTest/SwatchesLayeredNavigation/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Tax/composer.json | 2 +- .../Magento/FunctionalTest/TaxImportExport/composer.json | 2 +- .../functional/Magento/FunctionalTest/Translation/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Ui/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Ups/composer.json | 2 +- .../functional/Magento/FunctionalTest/UrlRewrite/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/User/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Usps/composer.json | 2 +- .../functional/Magento/FunctionalTest/Variable/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Vault/composer.json | 2 +- .../functional/Magento/FunctionalTest/Version/composer.json | 2 +- .../functional/Magento/FunctionalTest/Webapi/composer.json | 2 +- .../Magento/FunctionalTest/WebapiSecurity/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Weee/composer.json | 2 +- .../functional/Magento/FunctionalTest/Widget/composer.json | 2 +- .../Magento/FunctionalTest/WishlistAnalytics/composer.json | 2 +- dev/tests/functional/composer.json | 2 +- 109 files changed, 109 insertions(+), 109 deletions(-) diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdminNotification/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdminNotification/composer.json index 49a59426cfa6d..c6ec48b2930e5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdminNotification/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdminNotification/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedPricingImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedPricingImportExport/composer.json index 96be03e146356..4c0832605ae1d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedPricingImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedPricingImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/composer.json index cb59843c9cba8..9245dc6e40766 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorization/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorization/composer.json index 2eab99a968a9a..4e78766d9d135 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorization/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorization/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorizenet/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorizenet/composer.json index 06dce68805cd9..80d7737565277 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorizenet/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorizenet/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/composer.json index b2a99b07f0255..2d2dd01724f81 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backup": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backup/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backup/composer.json index c6e51064c592f..a77c84d925563 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backup/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backup/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Braintree/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Braintree/composer.json index d3a13786a0a9d..e91cba389bbff 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Braintree/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Braintree/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/composer.json index f2dd821d4fc36..4a724336f1d2c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/BundleImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/BundleImportExport/composer.json index fd79ec03d4ea9..1653aebe65ded 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/BundleImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/BundleImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-bundle": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CacheInvalidate/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CacheInvalidate/composer.json index f59864d2a14ea..3d8072140d268 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CacheInvalidate/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CacheInvalidate/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-page-cache": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Captcha/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Captcha/composer.json index 0297dbb343bcb..6b5beca7862e1 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Captcha/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Captcha/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogAnalytics/composer.json index cce1015d0d2e5..b742218731f84 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogImportExport/composer.json index b2b0b3965429a..22866e9abd2c1 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogInventory/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogInventory/composer.json index 432acba351bc3..ba124db346ae5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogInventory/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogInventory/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/composer.json index 49b2aeb653fb1..b478cb58583b5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRuleConfigurable/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRuleConfigurable/composer.json index 62be67eaed6da..b232f1e8563b0 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRuleConfigurable/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRuleConfigurable/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogUrlRewrite/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogUrlRewrite/composer.json index a6b42de511466..771e0385eccbc 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogUrlRewrite/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogUrlRewrite/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogWidget/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogWidget/composer.json index 5550db57606ba..1427c1af64b02 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogWidget/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogWidget/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CheckoutAgreements/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CheckoutAgreements/composer.json index fe061803b297b..8860639e22883 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CheckoutAgreements/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CheckoutAgreements/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/composer.json index 07aa529e45e14..c1d868e742226 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CmsUrlRewrite/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CmsUrlRewrite/composer.json index 7c35ddafd671d..c4ad8b0dc2f71 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CmsUrlRewrite/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CmsUrlRewrite/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-cms": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/composer.json index 4f3c721c582b1..b556ce773a6d3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableImportExport/composer.json index 2d8699d4999d5..b512f02910419 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductSales/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductSales/composer.json index 629ead23ae981..36389d2cc51bb 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductSales/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductSales/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Contact/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Contact/composer.json index b77a865b04de1..928012f706a4a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Contact/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Contact/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-cms": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cookie/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cookie/composer.json index 4d55d54479092..9aff0ad424117 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cookie/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cookie/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-store": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cron/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cron/composer.json index ad913508c5cbb..a4136569d26fc 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cron/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cron/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-store": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CurrencySymbol/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CurrencySymbol/composer.json index 335cee4939672..f11a1371b395a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CurrencySymbol/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CurrencySymbol/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/composer.json index e6e178fbcd163..e75cac61cb228 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerAnalytics/composer.json index 6082e25ee87ac..84a73e12eb4ff 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-customer": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerImportExport/composer.json index 09caca0289949..a63a0cc71af20 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Deploy/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Deploy/composer.json index 6cc25c9975ac9..49a9b5333133e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Deploy/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Deploy/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-config": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Developer/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Developer/composer.json index d20bf30c17289..ec19ec7de8e37 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Developer/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Developer/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-config": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Dhl/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Dhl/composer.json index 9d2da35038bfe..6ce6995f55137 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Dhl/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Dhl/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Directory/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Directory/composer.json index 8262f404e93a3..30a6dccdd6876 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Directory/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Directory/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/composer.json index d1972e5d5dd9a..400738980fd06 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/DownloadableImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/DownloadableImportExport/composer.json index 2c3b8fd9ce566..5078e028732b4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/DownloadableImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/DownloadableImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Eav/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Eav/composer.json index 06db9b63d7387..e14cf4a78bc3f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Eav/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Eav/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Email/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Email/composer.json index e95fc4ca907e3..6627c6b77fd0d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Email/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Email/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/EncryptionKey/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/EncryptionKey/composer.json index 0252e03b31808..371c1f30b8dab 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/EncryptionKey/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/EncryptionKey/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Fedex/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Fedex/composer.json index 5cf3ea9132e2a..1cf32f0772260 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Fedex/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Fedex/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GiftMessage/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GiftMessage/composer.json index 5cc515e5922d9..a00f20427c706 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GiftMessage/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GiftMessage/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAdwords/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAdwords/composer.json index 8710e25cd469d..cd3804122ec1f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAdwords/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAdwords/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-sales": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAnalytics/composer.json index 63b7597a9d391..3ac4ba7a20c08 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-cookie": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleOptimizer/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleOptimizer/composer.json index 71d48969544e3..7bd4832051827 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleOptimizer/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleOptimizer/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GraphQl/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GraphQl/composer.json index 701ed734f896c..05749f8295eba 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GraphQl/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GraphQl/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-webapi": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedImportExport/composer.json index 4460aef0ac60f..a5f2f1d4c9b3f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/composer.json index 3ab2160e33de9..4f4638a6e31cb 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ImportExport/composer.json index 4632adb4f904f..c575fa78375de 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Indexer/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Indexer/composer.json index 35b8219186bd2..c8b81673fe810 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Indexer/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Indexer/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/InstantPurchase/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/InstantPurchase/composer.json index 84c595020968c..b4e471fd62ed6 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/InstantPurchase/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/InstantPurchase/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-store": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Integration/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Integration/composer.json index 9f0ccb76c1cd3..3fcda364a88cc 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Integration/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Integration/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/LayeredNavigation/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/LayeredNavigation/composer.json index 447f3ba38a06c..dc2725e4a1d1e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/LayeredNavigation/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/LayeredNavigation/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Marketplace/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Marketplace/composer.json index d4079dfefc9ba..7f0909ff460a6 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Marketplace/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Marketplace/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MediaStorage/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MediaStorage/composer.json index 29657d03014bf..ef0cf6d0e7ec5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MediaStorage/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MediaStorage/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Msrp/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Msrp/composer.json index b91aaddcba3f2..5d1d5b4e3f74a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Msrp/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Msrp/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Multishipping/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Multishipping/composer.json index ffd80908ed522..cbc1fd9519105 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Multishipping/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Multishipping/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/NewRelicReporting/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/NewRelicReporting/composer.json index c6b60c43b6de0..014a5773c9520 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/NewRelicReporting/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/NewRelicReporting/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/composer.json index eff14e85b04a0..131cc853f0438 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflinePayments/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflinePayments/composer.json index f645c45abfdd0..f4adf1b4a8603 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflinePayments/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflinePayments/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflineShipping/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflineShipping/composer.json index 2fc319facc683..fb6bcd89a5c00 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflineShipping/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflineShipping/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/composer.json index 2c4612b71a126..c932ed0861247 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Payment/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Payment/composer.json index ea5f918171c8f..2f2b7fb8675e1 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Payment/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Payment/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Paypal/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Paypal/composer.json index 94c3af772673e..9af738c291089 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Paypal/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Paypal/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/composer.json index e12542a65d2be..ec4f6754e5838 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductAlert/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductAlert/composer.json index 1dc3837e4b1fb..93e3633101a8b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductAlert/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductAlert/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductVideo/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductVideo/composer.json index 0e1f83433049a..c3766646ad050 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductVideo/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductVideo/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Quote/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Quote/composer.json index 7d3a16063745f..4394d1f6ad3ad 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Quote/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Quote/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/QuoteAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/QuoteAnalytics/composer.json index 0d249b0c40921..4bd28d1b3c903 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/QuoteAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/QuoteAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-quote": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Reports/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Reports/composer.json index 53d7e7b1c9c0e..f76c29252118a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Reports/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Reports/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/RequireJs/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/RequireJs/composer.json index 2fcf3dc4c6103..b184fe40ce33b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/RequireJs/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/RequireJs/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Review/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Review/composer.json index 4445be9e856cf..10bcc87798b8c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Review/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Review/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ReviewAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ReviewAnalytics/composer.json index d58c62a68dac5..546a20fe50c0f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ReviewAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ReviewAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-review": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Robots/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Robots/composer.json index 70cf4ba3203e4..3b83ca8565b05 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Robots/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Robots/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-store": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rss/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rss/composer.json index 9fa6d370cd610..80ec362c2ce2e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rss/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rss/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rule/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rule/composer.json index 73dd74c5fa576..30f200468e3f9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rule/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rule/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/composer.json index a6c8fbebe72fc..9c1805b3df12a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesAnalytics/composer.json index 3f96160f374d0..0b37233aa5927 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-sales": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesInventory/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesInventory/composer.json index 6547bff428193..c4ab23c2d110e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesInventory/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesInventory/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesSequence/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesSequence/composer.json index 808f1394d6173..fb83f886ec02d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesSequence/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesSequence/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleData/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleData/composer.json index ed12f8bda3beb..8b531192d0fe1 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleData/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleData/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/composer.json index e0ceb5bd23c1c..81528e77bf827 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/composer.json index dc91e593e745b..7fdf84d34f99f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Security/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Security/composer.json index 69f18fcfbc40f..2ecb67d87d8ca 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Security/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Security/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SendFriend/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SendFriend/composer.json index 0b7d03fa71fa7..5f8bcdf51630f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SendFriend/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SendFriend/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/composer.json index fbe922ddc2d5c..bbd403aa22894 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/composer.json index 6d1c9eb72dab4..4ec67bdb7e675 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/composer.json index 718efc04391ca..506e9cc06fdff 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/composer.json index b9460ce939e86..ece658104cfe0 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/composer.json index 9632be9c9f172..1afb21a4e87bd 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/composer.json index 0931a3c286d0a..330478b6e929d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json index fb47e3fbeba58..8c50d2d39a5f0 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/composer.json index 364981ffd1e95..aff82b7a84e05 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/composer.json index 3a0fb712810ad..c44f92a1dfcb9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/composer.json index 219f938fed196..905890a4cea9a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/composer.json index 11aea7bbc68b7..06534e3b2b469 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/composer.json index d88d9a54264ee..ab7e60435564d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/composer.json index 07c2ed3745de5..e4ab9263b5c9c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Usps/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Usps/composer.json index 5896bff636205..4a6d5462d8016 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Usps/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Usps/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/composer.json index d70e75da77a03..386ebdeedbf47 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Vault/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Vault/composer.json index 88ce9046df10c..9fa8fc8f6b6ec 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Vault/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Vault/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Version/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Version/composer.json index 8a256bc40d42a..69078adc39303 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Version/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Version/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Webapi/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Webapi/composer.json index a00dbd244615f..7ddb760e9eb11 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Webapi/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Webapi/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WebapiSecurity/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WebapiSecurity/composer.json index 3c26635fc3f6e..5ec58e1ff9e0f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WebapiSecurity/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WebapiSecurity/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-webapi": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Weee/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Weee/composer.json index b226f2b1697fa..019d957e96c54 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Weee/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Weee/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Widget/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Widget/composer.json index 85c1d19bd696c..94a03b6c64eeb 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Widget/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Widget/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WishlistAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WishlistAnalytics/composer.json index 1f25efea7f90f..b49a321f44884 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WishlistAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WishlistAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/magento2-functional-test-module-wishlist": "100.0.0-dev" diff --git a/dev/tests/functional/composer.json b/dev/tests/functional/composer.json index a43a3390daa9a..0c9f329f234a8 100644 --- a/dev/tests/functional/composer.json +++ b/dev/tests/functional/composer.json @@ -3,7 +3,7 @@ "sort-packages": true }, "require": { - "php": "~7.1.3||~7.2.0", + "php": "7.0.2|~7.0.6|~7.1.0", "magento/mtf": "1.0.0-rc59", "allure-framework/allure-phpunit": "~1.2.0", "doctrine/annotations": "1.4.*", From 4c20da85b69f534af67c08336c0644dfbce82962 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@magento.com> Date: Mon, 12 Mar 2018 16:46:35 -0500 Subject: [PATCH 051/668] MAGETWO-89178: Create integration or functional test - ported graphQl test for configurable product options --- .../ConfigurableProductViewTest.php | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php index e5b2067faf402..5f8724a00bbf6 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php @@ -8,7 +8,10 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\ConfigurableProduct\Api\Data\OptionInterface; +use Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute; use Magento\TestFramework\ObjectManager; +use Magento\ConfigurableProduct\Api\OptionRepositoryInterface; use Magento\TestFramework\TestCase\GraphQlAbstract; class ConfigurableProductViewTest extends GraphQlAbstract @@ -83,6 +86,17 @@ public function testQueryConfigurableProductLinks() } category_ids ... on ConfigurableProduct { + configurable_product_options{ + id + attribute_id + label + position + is_use_default + values{ + value_index + } + product_id + } configurable_product_links { id category_ids @@ -188,6 +202,7 @@ public function testQueryConfigurableProductLinks() $this->assertArrayHasKey(0, $response['products']['items']); $this->assertBaseFields($product, $response['products']['items'][0]); $this->assertConfigurableProductLinks($response['products']['items'][0]); + $this->assertConfigurableProductOptions($response['products']['items'][0]); } /** @@ -373,6 +388,50 @@ private function assertConfigurableProductLinks($actualResponse) } } + private function assertConfigurableProductOptions($actualResponse) + { + $this->assertNotEmpty( + $actualResponse['configurable_product_options'], + "Precondition failed: 'configurable_product_options' must not be empty" + ); + $productSku = 'configurable'; + /** @var OptionRepositoryInterface $optionRepository */ + $optionRepository = ObjectManager::getInstance()->get(OptionRepositoryInterface::class); + $configurableAttributeOptions = $optionRepository->getList($productSku); + $configurableAttributeOption = $configurableAttributeOptions[0]; + /** @var Attribute $attribute */ + //$attribute = ObjectManager::getInstance()->get(Attribute::class); + /** @var OptionInterface $option */ + $option = ObjectManager::getInstance()->get(OptionInterface::class); + + // TODO: uncomment the assertions once issue MAGETWO-88216 is fixed. + //$this->assertEquals($actualResponse['configurable_product_options'][0]['id'], $configurableAttributeOption->getId()); + // $this->assertEquals($actualResponse['configurable_product_options'][0]['is_use_default'], (bool)$attribute->getIsUseDefault()); + $this->assertEquals( + $actualResponse['configurable_product_options'][0]['attribute_id'], + $configurableAttributeOption->getAttributeId() + ); + $this->assertEquals( + $actualResponse['configurable_product_options'][0]['label'], + $configurableAttributeOption->getLabel() + ); + $this->assertEquals( + $actualResponse['configurable_product_options'][0]['position'], + $configurableAttributeOption->getPosition() + ); + $this->assertEquals( + $actualResponse['configurable_product_options'][0]['product_id'], + $configurableAttributeOption->getProductId() + ); + // $this->assertEquals($actualResponse['configurable_product_options'][0]['is_use_default'], $option->getIsUseDefault()); + /*foreach ($actualResponse['configurable_product_options'][0]['values'] as $value) { + $this->assertEquals( + $actualResponse ['configurable_product_options'][0]['values'][$value]['value_index'], + $configurableAttributeOption->getOptions()[$value]['value_index'] + ); + }*/ + } + /** * @param array $actualResponse * @param array $assertionMap ['response_field_name' => 'response_field_value', ...] From a1636518c311aef1883c05a74942b1f0a4d89e3a Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@magento.com> Date: Mon, 12 Mar 2018 17:03:22 -0500 Subject: [PATCH 052/668] MAGETWO-89178: Create integration or functional test - ported graphQl test for product links field --- .../Model/ProductLinksTypeResolver.php | 2 +- .../GraphQl/Catalog/ProductViewTest.php | 58 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/ProductLinksTypeResolver.php b/app/code/Magento/CatalogGraphQl/Model/ProductLinksTypeResolver.php index 635de09e52fbd..1dee8b0d8b6ff 100644 --- a/app/code/Magento/CatalogGraphQl/Model/ProductLinksTypeResolver.php +++ b/app/code/Magento/CatalogGraphQl/Model/ProductLinksTypeResolver.php @@ -23,7 +23,7 @@ class ProductLinksTypeResolver implements TypeResolverInterface */ public function resolveType(array $data) { - if (isset($data['type_id'])) { + if (isset($data['link_type'])) { $linkType = $data['link_type']; if (in_array($linkType, $this->linkTypes)) { return 'ProductLinks'; diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index b33503b7ddf6d..8a62dc85f8808 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -7,6 +7,7 @@ namespace Magento\GraphQl\Catalog; use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Api\Data\ProductLinkInterface; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\GraphQlAbstract; @@ -520,6 +521,43 @@ public function testQueryCustomAttributeField() $this->assertCustomAttribute($response['products']['items'][0]); } + /** + * @magentoApiDataFixture Magento/Catalog/_files/products_related.php + */ + public function testProductLinks() + { + $productSku = 'simple_with_cross'; + + $query = <<<QUERY + { + products(filter: {sku: {eq: "{$productSku}"}}) + { + items { + attribute_set_id + type_id + product_links + { + link_type + linked_product_sku + linked_product_type + position + sku + } + } + } + } +QUERY; + + $response = $this->graphQlQuery($query); + /** + * @var ProductRepositoryInterface $productRepository + */ + $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); + $product = $productRepository->get($productSku, false, null, true); + $this->assertNotNull($response['products']['items'][0]['product_links'], "product_links must not be null"); + $this->assertProductLinks($product, $response['products']['items'][0]['product_links'][0]); + } + /** * @param ProductInterface $product * @param array $actualResponse @@ -741,6 +779,26 @@ private function assertBaseFields($product, $actualResponse) $this->assertResponseFields($actualResponse, $assertionMap); } + /** + * @param ProductInterface $product + * @param array $actualResponse + */ + private function assertProductLinks($product, $actualResponse) + { + /** @var ProductLinkInterface $productLinks */ + $productLinks = $product->getProductLinks(); + $productLink = $productLinks[0]; + // $this->assertNotEmpty($actualResponse['product_links'],"Precondition failed: 'product_links' must not be empty"); + $assertionMap = [ + ['response_field' => 'link_type', 'expected_value' => $productLink->getLinkType()], + ['response_field' => 'linked_product_sku', 'expected_value' => $productLink->getLinkedProductSku()], + ['response_field' => 'linked_product_type', 'expected_value' => $productLink->getLinkedProductType()], + ['response_field' => 'position', 'expected_value' => $productLink->getPosition()], + ['response_field' => 'sku', 'expected_value' => $productLink->getSku()], + ]; + $this->assertResponseFields($actualResponse, $assertionMap); + } + /** * @param ProductInterface $product * @param array $actualResponse From fe7c1e2d0ddaf5faf2c44b9bc11a6dbafa07e551 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@magento.com> Date: Mon, 12 Mar 2018 17:22:32 -0500 Subject: [PATCH 053/668] MAGETWO-89178: Create integration or functional test - integration test for GraphQl Config Structure --- .../Framework/GraphQl/GraphQlConfigTest.php | 138 ++++++++ .../GraphQl/_files/graphql_config1.xml | 304 ++++++++++++++++++ .../GraphQl/_files/graphql_config2.xml | 25 ++ .../GraphQl/_files/query_array_output.php | 205 ++++++++++++ 4 files changed, 672 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Framework/GraphQl/GraphQlConfigTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/graphql_config1.xml create mode 100644 dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/graphql_config2.xml create mode 100644 dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/GraphQlConfigTest.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/GraphQlConfigTest.php new file mode 100644 index 0000000000000..1aa5d49caffa7 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/GraphQlConfigTest.php @@ -0,0 +1,138 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\GraphQl; + +use Magento\Framework\App\Bootstrap; +use Magento\Framework\App\Cache; +use Magento\Framework\Config\FileResolverInterface; +use Magento\Framework\GraphQl\Config\Config; +use Magento\Framework\GraphQl\Config\Data\Argument; +use Magento\Framework\GraphQl\Config\Data\Enum; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Config\Data\StructureInterface; +use Magento\Framework\GraphQl\Config\Data\Type; +use Magento\Framework\ObjectManagerInterface; + +class GraphQlConfigTest extends \PHPUnit\Framework\TestCase +{ + /** @var Config */ + private $model; + + protected function setUp() + { + /** @var ObjectManagerInterface $objectManager */ + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + /** @var Cache $cache */ + $cache = $objectManager->get(Cache::class); + $cache->clean(); + $fileResolverMock = $this->getMockBuilder( + \Magento\Framework\Config\FileResolverInterface::class + )->disableOriginalConstructor()->getMock(); + // $fileList = file_get_contents(__DIR__ . '/_files/graphql_config1.xml'); + $fileList = [ + file_get_contents(__DIR__ . '/_files/graphql_config1.xml'), + file_get_contents(__DIR__ . '/_files/graphql_config2.xml') + ]; + + $fileResolverMock->expects($this->any())->method('get')->will($this->returnValue($fileList)); + /** @var FileResolverInterface $fileResolver */ + // $fileResolver = $objectManager->get(FileResolverInterface::class); + // $fileList = file_get_contents(__DIR__ . '/_files/graphql_config1.xml'); + // $fileResolver->get($fileList,'global'); + $xmlReader = $objectManager->create(\Magento\Framework\GraphQl\Config\XmlReader::class, + ['fileResolver' => $fileResolverMock] + ); + + $reader = $objectManager->create( + \Magento\Framework\GraphQl\Config\Reader::class, + ['readers' => ['xmlReader' =>$xmlReader]] + ); + $data = $objectManager->create(\Magento\Framework\GraphQl\Config\Data ::class, + ['reader' => $reader] + ); + $this->model = $objectManager->create(\Magento\Framework\GraphQl\Config\Config::class, ['data' =>$data]); + } + + /** + * Testing if GraphQl Xml reader is able to merge xmls based on graphql/di.xml and transforms to a normalized structure + */ + public function testGraphQlTypeAndFieldConfigStructure() + { + $query = 'Query'; + + /** @var StructureInterface $outputType */ + $output = $this->model->getTypeStructure($query); + $expectedOutputArray = require __DIR__ . '/_files/query_array_output.php'; + $this->assertEquals($output->getName(), $query); + + /** @var Field $queryFields */ + $queryFields = $output->getFields(); + + foreach (array_keys($queryFields) as $fieldKey) { + $this->assertEquals($expectedOutputArray['Query']['fields'][$fieldKey]['name'], $queryFields[$fieldKey]->getName()); + $this->assertEquals($expectedOutputArray['Query']['fields'][$fieldKey]['type'],$queryFields[$fieldKey]->getType()); + $this->assertEquals($expectedOutputArray['Query']['fields'][$fieldKey]['resolver'],$queryFields[$fieldKey]->getResolver()); + /** @var Argument $queryFieldArguments */ + $queryFieldArguments = $queryFields[$fieldKey]->getArguments(); + foreach(array_keys($queryFieldArguments) as $argumentKey){ + $this->assertEquals($expectedOutputArray['Query']['fields'][$fieldKey]['arguments'][$argumentKey]['type'],$queryFieldArguments[$argumentKey]->getType()); + $this->assertEquals($expectedOutputArray['Query']['fields'][$fieldKey]['arguments'][$argumentKey]['name'],$queryFieldArguments[$argumentKey]->getName()); + $this->assertEquals($expectedOutputArray['Query']['fields'][$fieldKey]['arguments'][$argumentKey]['description'],$queryFieldArguments[$argumentKey]->getDescription()); + } + } + } + + public function testGraphQlEnumTypeConfigStructure() + { + $queryEnum = 'PriceAdjustmentDescriptionEnum'; + /** @var Enum $outputEnum */ + $outputEnum = $this->model->getTypeStructure($queryEnum); + /** @var Enum\Value $outputEnumValues */ + $outputEnumValues = $outputEnum->getValues(); + $expectedOutputArray = require __DIR__ . '/_files/query_array_output.php'; + $this->assertEquals($outputEnum->getName(), $queryEnum); + foreach(array_keys($outputEnumValues) as $outputEnumValue) { + $this->assertEquals($expectedOutputArray['PriceAdjustmentDescriptionEnum']['items'][$outputEnumValue]['name'], $outputEnumValues[$outputEnumValue]->getName()); + $this->assertEquals($expectedOutputArray['PriceAdjustmentDescriptionEnum']['items'][$outputEnumValue]['_value'], $outputEnumValues[$outputEnumValue]->getValue()); + } + } + + public function testGraphQlInterfaceStructure() + { + $inputInterfaceType = 'ProductLinks'; + /** @var Type $outputInterface */ + $outputInterface = $this->model->getTypeStructure($inputInterfaceType); + $expectedOutputArray = require __DIR__ . '/_files/query_array_output.php'; + $this->assertEquals($outputInterface->getName(), $inputInterfaceType); + + $outputInterfaceValues = $outputInterface->getInterfaces(); + /** @var Field $outputInterfaceFields */ + $outputInterfaceFields =$outputInterface->getFields(); + foreach(array_keys($outputInterfaceValues) as $outputInterfaceValue){ + $this->assertEquals($expectedOutputArray['ProductLinks']['implements'][$outputInterfaceValue]['interface'], $outputInterfaceValues[$outputInterfaceValue]['interface']); + $this->assertEquals($expectedOutputArray['ProductLinks']['implements'][$outputInterfaceValue]['copyFields'], $outputInterfaceValues[$outputInterfaceValue]['copyFields']); + } + foreach(array_keys($outputInterfaceFields) as $outputInterfaceField) { + $this->assertEquals($expectedOutputArray['ProductLinks']['fields'][$outputInterfaceField]['name'], $outputInterfaceFields[$outputInterfaceField]->getName()); + $this->assertEquals($expectedOutputArray['ProductLinks']['fields'][$outputInterfaceField]['type'], $outputInterfaceFields[$outputInterfaceField]->getType()); + $this->assertEquals($expectedOutputArray['ProductLinks']['fields'][$outputInterfaceField]['required'], $outputInterfaceFields[$outputInterfaceField]->isRequired()); + $this->assertEquals($expectedOutputArray['ProductLinks']['fields'][$outputInterfaceField]['description'], $outputInterfaceFields[$outputInterfaceField]->getDescription()); + $this->assertEmpty($outputInterfaceFields[$outputInterfaceField]->getArguments()); + } + } + + /** + * {@inheritdoc} + */ + protected function tearDown() + { + /** @var ObjectManagerInterface $objectManager */ + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + /** @var Cache $cache */ + $cache = $objectManager->get(Cache::class); + $cache->clean(); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/graphql_config1.xml b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/graphql_config1.xml new file mode 100644 index 0000000000000..faa358c51a685 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/graphql_config1.xml @@ -0,0 +1,304 @@ +<?xml version="1.0"?> +<!-- + Copyright © Magento, Inc. All rights reserved. + See COPYING.txt for license details. + --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> + <type xsi:type="OutputType" name="Query"> + <field xsi:type="ObjectOutputField" name="products" type="Products" resolver="Magento\Framework\GraphQlPersistence\Resolver\Query\Resolver"> + <argument xsi:type="ScalarArgument" name="search" type="String" description="Text to be used in a full text search. If multiple keywords are specified, each keyword is evaluated separately."/> + <argument xsi:type="ObjectArgument" name="filter" type="ProductFilterInput" description="Defines which search criteria to use to find the desired results. Each filter defines the field or fields to be searched, the condition type, and the search value."/> + <argument xsi:type="ScalarArgument" name="pageSize" type="Int" description="The maximum number of items to return. If no value is specified, the search returns 20 items."/> + <argument xsi:type="ScalarArgument" name="currentPage" type="Int" description="Specifies which page of results to return. If no value is specified, the first page is returned. If you specify a value that is greater than the number of available pages, an error is returned."/> + <argument xsi:type="ObjectArgument" name="sort" type="ProductSortInput" description="Specifies which field or fields to use for sorting the results. If you specify more than one field, Magento sorts by the first field listed. Then, if any items have the same value, those items will be sorted by the secondary field. The value for each field can be set to either ASC (ascending) or DESC (descending)."/> + </field> + </type> + <type xsi:type="Enum" name="PriceAdjustmentDescriptionEnum"> + <item name="included">INCLUDED</item> + <item name="excluded">EXCLUDED</item> + </type> + <type xsi:type="OutputType" name="Money"> + <field xsi:type="ScalarOutputField" name="value" type="Float" description="A number expressing a monetary value."/> + <field xsi:type="ObjectOutputField" name="currency" type="CurrencyEnum" description="A three-letter currency code, such as `USD` or `EUR`."/> + </type> + <type xsi:type="OutputType" name="Price"> + <field xsi:type="ObjectOutputField" name="amount" type="Money" description="The price of a product plus a three-letter currency code."/> + <field xsi:type="ObjectArrayOutputField" name="adjustments" itemType="PriceAdjustment" description="An array that provides information about tax, weee, or weee_tax adjustments."/> + </type> + <type xsi:type="OutputType" name="PriceAdjustment"> + <field xsi:type="ObjectOutputField" name="amount" type="Money" description="The amount of the price adjustment and its currency code."/> + <field xsi:type="ObjectOutputField" name="code" type="PriceAdjustmentCodesEnum" description="Indicates whether the adjustment involves tax, weee, or weee_tax"/> + <field xsi:type="ObjectOutputField" name="description" type="PriceAdjustmentDescriptionEnum" description="Indicates whether the entity described by the code attribute is included or excluded from the adjustment."/> + </type> + <type xsi:type="OutputType" name="ProductPrices"> + <field xsi:type="ObjectOutputField" name="minimalPrice" type="Price" description="Used for composite (bundle, configurable, grouped) products. This is the lowest possible final price for all the options defined within a composite product. If you're specifying a price range, this would be the 'from' value."/> + <field xsi:type="ObjectOutputField" name="maximalPrice" type="Price" description="Used for composite (bundle, configurable, grouped) products. This is the highest possible final price for all the options defined within a composite product. If you're specifying a price range, this would be the 'to' value."/> + <field xsi:type="ObjectOutputField" name="regularPrice" type="Price" description="The base price of a product."/> + </type> + <type xsi:type="OutputType" name="ProductCategoryLinks"> + <field xsi:type="ScalarOutputField" name="position" type="Int" description="The position of the category in the category tree"/> + <field xsi:type="ScalarOutputField" name="category_id" type="String" description="The unique identifier for the category"/> + </type> + <type xsi:type="OutputInterface" name="ProductLinksInterface" typeResolver="Magento\CatalogGraphQl\Model\ProductLinkTypeResolverComposite"> + <field xsi:type="ScalarOutputField" name="sku" type="String" description="The identifier of the linked product"/> + <field xsi:type="ScalarOutputField" name="link_type" type="String" description="One of 'related', 'associated', 'upsell', or 'crosssell'."/> + <field xsi:type="ScalarOutputField" name="linked_product_sku" type="String" description="The SKU of the linked product"/> + <field xsi:type="ScalarOutputField" name="linked_product_type" type="String" description="The type of linked product ('simple', 'virtual', 'bundle', 'downloadable','grouped', 'configurable')"/> + <field xsi:type="ScalarOutputField" name="position" type="Int" description="The position within the list of product links"/> + </type> + <type xsi:type="OutputType" name="ProductLinks"> + <implements interface="ProductLinksInterface" copyFields="true"/> + </type> + <type xsi:type="OutputType" name="ProductTierPrices"> + <field xsi:type="ScalarOutputField" name="customer_group_id" type="Int" description="The ID of the customer group"/> + <field xsi:type="ScalarOutputField" name="qty" type="Float" description="The number of items that must be purchased to qualify for tier pricing."/> + <field xsi:type="ScalarOutputField" name="value" type="Float" description="The price of the fixed price item"/> + <field xsi:type="ScalarOutputField" name="percentage_value" type="Float" description="The percentage discount of the item"/> + <field xsi:type="ScalarOutputField" name="website_id" type="Float" description="The ID assigned to the website"/> + <field xsi:type="ScalarOutputField" name="customer_group_id" type="String" description="The ID of the customer group"/> + </type> + <type xsi:type="OutputInterface" name="ProductInterface" typeResolver="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> + <field xsi:type="ScalarOutputField" name="id" type="Int" description="The ID number assigned to the product."/> + <field xsi:type="ScalarOutputField" name="name" type="String" description="The product name. Customers use this name to identify the product."/> + <field xsi:type="ScalarOutputField" name="sku" type="String" description="A number or code assigned to a product to identify the product, options, price, and manufacturer."/> + <field xsi:type="ScalarOutputField" name="description" type="String" description="A detailed information about the product. The value can include simple HTML tags."/> + <field xsi:type="ScalarOutputField" name="short_description" type="String" description="A short description of the product. Its use depends on the theme."/> + <field xsi:type="ScalarOutputField" name="special_price" type="Float" description="The discounted price of the product"/> + <field xsi:type="ScalarOutputField" name="special_from_date" type="String" description="The beginning date that a product has a special price."/> + <field xsi:type="ScalarOutputField" name="special_to_date" type="String" description="The end date that a product has a special price."/> + <field xsi:type="ScalarOutputField" name="attribute_set_id" type="Int" description="The attribute set assigned to the product."/> + <field xsi:type="ScalarOutputField" name="meta_title" type="String" description="A string that is displayed in the title bar and tab of the browser and in search results lists."/> + <field xsi:type="ScalarOutputField" name="meta_keyword" type="String" description="A comma-separated list of keywords that are visible only to search engines."/> + <field xsi:type="ScalarOutputField" name="meta_description" type="String" description="A brief overview of the product for search results listings. Maximum 255 characters."/> + <field xsi:type="ScalarOutputField" name="image" type="String" description="The relative path for the main image on the product page."/> + <field xsi:type="ScalarOutputField" name="small_image" type="String" description="The file name of a small image, which is used on catalog pages."/> + <field xsi:type="ScalarOutputField" name="thumbnail" type="String" description="The file name of a thumbnail image"/> + <field xsi:type="ScalarOutputField" name="new_from_date" type="String" description="The beginning date for new product listings, and determines if the product is featured as a new product. Note: The input attribute name is 'news_from_date'."/> + <field xsi:type="ScalarOutputField" name="new_to_date" type="String" description="The end date for new product listings. Note: The input attribute name is 'news_to_date'."/> + <field xsi:type="ScalarOutputField" name="tier_price" type="Float" description="The price when tier pricing is in effect and the items purchased threshold has been reached."/> + <field xsi:type="ScalarOutputField" name="custom_design" type="String" description="A theme that can be applied to the product page."/> + <field xsi:type="ScalarOutputField" name="custom_design_from" type="String" description="The beginning date when a theme is applied to the product page."/> + <field xsi:type="ScalarOutputField" name="custom_design_to" type="String" description="The date at which a theme is no longer applied to the product page."/> + <field xsi:type="ScalarOutputField" name="custom_layout_update" type="String" description="XML code that is applied as a layout update to the product page."/> + <field xsi:type="ScalarOutputField" name="custom_layout" type="String" description="The name of a custom layout."/> + <field xsi:type="ScalarOutputField" name="page_layout" type="String" description="The page layout of the product page. Values include '1column-center', '2columns-left', '2columns-right', and '3columns'."/> + <field xsi:type="ScalarArrayOutputField" name="category_ids" itemType="Int" description="An array of category IDs the product belongs to."/> + <field xsi:type="ScalarOutputField" name="options_container" type="String" description="If the product has multiple options, determines where they appear on the product page."/> + <field xsi:type="ScalarOutputField" name="image_label" type="String" description="The label assigned to a product image."/> + <field xsi:type="ScalarOutputField" name="small_image_label" type="String" description="The label assigned to a product's small image."/> + <field xsi:type="ScalarOutputField" name="thumbnail_label" type="String" description="The label assigned to a product's thumbnail image."/> + <field xsi:type="ScalarOutputField" name="created_at" type="String" description="Timestamp indicating when a product was created"/> + <field xsi:type="ScalarOutputField" name="updated_at" type="String" description="The timestamp indicating when the product was last updated."/> + <field xsi:type="ScalarOutputField" name="country_of_manufacture" type="String" description="The product's country of origin"/> + <field xsi:type="ScalarOutputField" name="type_id" type="String" description="One of 'simple', 'virtual', 'bundle', 'downloadable','grouped', or 'configurable'"/> + <field xsi:type="ScalarArrayOutputField" name="website_ids" itemType="Int" description="An array of website IDs in which the product is available."/> + <field xsi:type="ObjectArrayOutputField" name="category_links" itemType="ProductCategoryLinks" description="An array that contains links to categories the product is assigned to."/> + <field xsi:type="ObjectArrayOutputField" name="product_links" itemType="ProductLinksInterface" description="An array that contains information about products that are related to the current product."/> + <field xsi:type="ObjectArrayOutputField" name="media_gallery_entries" itemType="MediaGalleryEntry" description="An array that contains information about the images and video assigned to this product."/> + <field xsi:type="ObjectArrayOutputField" name="tier_prices" itemType="ProductTierPrices" description="An array that defines tier prices for the item."/> + <field xsi:type="ObjectOutputField" name="price" type="ProductPrices" description="The price of the item, including the value and the currency code."/> + <field xsi:type="ScalarOutputField" name="gift_message_available" type="String" description="Indicates whether a gift message is available."/> + </type> + <type xsi:type="OutputInterface" name="PhysicalProductInterface" typeResolver="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> + <field xsi:type="ScalarOutputField" name="weight" type="Float" description="The weight of a physical product"/> + </type> + <type xsi:type="OutputInterface" name="CustomizableProductInterface" typeResolver="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> + <field xsi:type="ObjectArrayOutputField" name="options" itemType="CustomizableOptionInterface" description="An array containing information about the customizable options for a product"/> + </type> + <type xsi:type="OutputInterface" name="CustomizableOptionInterface" typeResolver="Magento\CatalogGraphQl\Model\CustomizableOptionTypeResolver"> + <field xsi:type="ScalarOutputField" name="title" type="String" description="The displayed name of the option"/> + <field xsi:type="ScalarOutputField" name="required" type="Boolean" description="Indicates whether the option is required"/> + <field xsi:type="ScalarOutputField" name="sort_order" type="Int" description="The order in which the option is displayed"/> + </type> + <type xsi:type="OutputType" name="VirtualProduct"> + <implements interface="ProductInterface" copyFields="true"/> + <implements interface="CustomizableProductInterface" copyFields="true"/> + </type> + <type xsi:type="OutputType" name="SimpleProduct"> + <implements interface="ProductInterface" copyFields="true"/> + <implements interface="PhysicalProductInterface" copyFields="true"/> + <implements interface="CustomizableProductInterface" copyFields="true"/> + </type> + <type xsi:type="InputType" name="ProductFilterInput"> + <field xsi:type="ObjectInputField" name="name" type="FilterTypeInput" description="The product name. Customers use this name to identify the product."/> + <field xsi:type="ObjectInputField" name="sku" type="FilterTypeInput" description="A number or code assigned to a product to identify the product, options, price, and manufacturer."/> + <field xsi:type="ObjectInputField" name="description" type="FilterTypeInput" description="A detailed information about the product. The value can include simple HTML tags."/> + <field xsi:type="ObjectInputField" name="short_description" type="FilterTypeInput" description="A short description of the product. Its use depends on the theme."/> + <field xsi:type="ObjectInputField" name="price" type="FilterTypeInput" description="The numeric price of the product. Do not include the currency code."/> + <field xsi:type="ObjectInputField" name="special_price" type="FilterTypeInput" description="The discounted price of the product"/> + <field xsi:type="ObjectInputField" name="special_from_date" type="FilterTypeInput" description="The beginning date that a product has a special price."/> + <field xsi:type="ObjectInputField" name="special_to_date" type="FilterTypeInput" description="The end date that a product has a special price."/> + <field xsi:type="ObjectInputField" name="weight" type="FilterTypeInput" description="The weight of the item, in units defined by the store"/> + <field xsi:type="ObjectInputField" name="manufacturer" type="FilterTypeInput" description="The company that created the item"/> + <field xsi:type="ObjectInputField" name="meta_title" type="FilterTypeInput" description="A string that is displayed in the title bar and tab of the browser and in search results lists."/> + <field xsi:type="ObjectInputField" name="meta_keyword" type="FilterTypeInput" description="A comma-separated list of keywords that are visible only to search engines."/> + <field xsi:type="ObjectInputField" name="meta_description" type="FilterTypeInput" description="A brief overview of the product for search results listings. Maximum 255 characters."/> + <field xsi:type="ObjectInputField" name="image" type="FilterTypeInput" description="The relative path for the main image on the product page."/> + <field xsi:type="ObjectInputField" name="small_image" type="FilterTypeInput" description="The file name of a small image, which is used on catalog pages."/> + <field xsi:type="ObjectInputField" name="thumbnail" type="FilterTypeInput" description="The file name of a thumbnail image"/> + <field xsi:type="ObjectInputField" name="tier_price" type="FilterTypeInput" description="The price when tier pricing is in effect and the items purchased threshold has been reached."/> + <field xsi:type="ObjectInputField" name="color" type="FilterTypeInput" description="A number assigned to represent the color"/> + <field xsi:type="ObjectInputField" name="news_from_date" type="FilterTypeInput" description="The beginning date for new product listings, and determines if the product is featured as a new product. Note: The output attribute name is 'new_from_date'."/> + <field xsi:type="ObjectInputField" name="news_to_date" type="FilterTypeInput" description="The end date for new product listings. Note: The output attribute name is 'new_to_date'."/> + <field xsi:type="ObjectInputField" name="custom_design" type="FilterTypeInput" description="A theme that can be applied to the product page."/> + <field xsi:type="ObjectInputField" name="custom_design_from" type="FilterTypeInput" description="The beginning date when a theme is applied to the product page."/> + <field xsi:type="ObjectInputField" name="custom_design_to" type="FilterTypeInput" description="The date at which a theme is no longer applied to the product page."/> + <field xsi:type="ObjectInputField" name="custom_layout_update" type="FilterTypeInput" description="XML code that is applied as a layout update to the product page."/> + <field xsi:type="ObjectInputField" name="page_layout" type="FilterTypeInput" description="The page layout of the product page. Values include '1column-center', '2columns-left', '2columns-right', and '3columns'."/> + <field xsi:type="ObjectInputField" name="category_ids" type="FilterTypeInput" description="An array of category IDs the product belongs to."/> + <field xsi:type="ObjectInputField" name="options_container" type="FilterTypeInput" description="If the product has multiple options, determines where they appear on the product page."/> + <field xsi:type="ObjectInputField" name="required_options" type="FilterTypeInput" description="Indicates whether the product has required options."/> + <field xsi:type="ObjectInputField" name="has_options" type="FilterTypeInput" description="Indicates whether additional attributes have been created for the product."/> + <field xsi:type="ObjectInputField" name="image_label" type="FilterTypeInput" description="The label assigned to a product image."/> + <field xsi:type="ObjectInputField" name="small_image_label" type="FilterTypeInput" description="The label assigned to a product's small image."/> + <field xsi:type="ObjectInputField" name="thumbnail_label" type="FilterTypeInput" description="The label assigned to a product's thumbnail image."/> + <field xsi:type="ObjectInputField" name="created_at" type="FilterTypeInput" description="Timestamp indicating when the product was created"/> + <field xsi:type="ObjectInputField" name="updated_at" type="FilterTypeInput" description="Timestamp indicating when the product was last updated"/> + <field xsi:type="ObjectInputField" name="country_of_manufacture" type="FilterTypeInput" description="The product's country of origin"/> + <field xsi:type="ObjectInputField" name="custom_layout" type="FilterTypeInput" description="The name of a custom layout."/> + <field xsi:type="ObjectInputField" name="gift_message_available" type="FilterTypeInput" description="Indicates whether a gift message is available."/> + <field xsi:type="ObjectInputField" name="or" type="ProductFilterInput" description="The keyword required to perform a logical OR comparison."/> + </type> + <type xsi:type="InputType" name="ProductSortInput"> + <field xsi:type="ObjectInputField" name="name" type="SortEnum" description="The product name. Customers use this name to identify the product."/> + <field xsi:type="ObjectInputField" name="sku" type="SortEnum" description="A number or code assigned to a product to identify the product, options, price, and manufacturer."/> + <field xsi:type="ObjectInputField" name="description" type="SortEnum" description="A detailed information about the product. The value can include simple HTML tags."/> + <field xsi:type="ObjectInputField" name="short_description" type="SortEnum" description="A short description of the product. Its use depends on the theme."/> + <field xsi:type="ObjectInputField" name="price" type="SortEnum" description="The numeric price of the product. Do not include the currency code."/> + <field xsi:type="ObjectInputField" name="special_price" type="SortEnum" description="The discounted price of the product"/> + <field xsi:type="ObjectInputField" name="special_from_date" type="SortEnum" description="The beginning date that a product has a special price."/> + <field xsi:type="ObjectInputField" name="special_to_date" type="SortEnum" description="The end date that a product has a special price."/> + <field xsi:type="ObjectInputField" name="weight" type="SortEnum" description="The weight of the item, in units defined by the store"/> + <field xsi:type="ObjectInputField" name="manufacturer" type="SortEnum" description="The company that created the item"/> + <field xsi:type="ObjectInputField" name="meta_title" type="SortEnum" description="A string that is displayed in the title bar and tab of the browser and in search results lists."/> + <field xsi:type="ObjectInputField" name="meta_keyword" type="SortEnum" description="A comma-separated list of keywords that are visible only to search engines."/> + <field xsi:type="ObjectInputField" name="meta_description" type="SortEnum" description="A brief overview of the product for search results listings. Maximum 255 characters."/> + <field xsi:type="ObjectInputField" name="image" type="SortEnum" description="The relative path for the main image on the product page."/> + <field xsi:type="ObjectInputField" name="small_image" type="SortEnum" description="The file name of a small image, which is used on catalog pages."/> + <field xsi:type="ObjectInputField" name="thumbnail" type="SortEnum" description="The file name of a thumbnail image"/> + <field xsi:type="ObjectInputField" name="tier_price" type="SortEnum" description="The price when tier pricing is in effect and the items purchased threshold has been reached."/> + <field xsi:type="ObjectInputField" name="color" type="SortEnum" description="A number assigned to represent the color"/> + <field xsi:type="ObjectInputField" name="news_from_date" type="SortEnum" description="The beginning date for new product listings, and determines if the product is featured as a new product. Note: The output attribute name is 'new_from_date'."/> + <field xsi:type="ObjectInputField" name="news_to_date" type="SortEnum" description="The end date for new product listings. Note: The output attribute name is 'new_to_date'."/> + <field xsi:type="ObjectInputField" name="custom_design" type="SortEnum" description="A theme that can be applied to the product page."/> + <field xsi:type="ObjectInputField" name="custom_design_from" type="SortEnum" description="The beginning date when a theme is applied to the product page."/> + <field xsi:type="ObjectInputField" name="custom_design_to" type="SortEnum" description="The date at which a theme is no longer applied to the product page."/> + <field xsi:type="ObjectInputField" name="custom_layout_update" type="SortEnum" description="XML code that is applied as a layout update to the product page."/> + <field xsi:type="ObjectInputField" name="page_layout" type="SortEnum" description="The page layout of the product page. Values include '1column-center', '2columns-left', '2columns-right', and '3columns'."/> + <field xsi:type="ObjectInputField" name="category_ids" type="SortEnum" description="An array of category IDs the product belongs to."/> + <field xsi:type="ObjectInputField" name="options_container" type="SortEnum" description="If the product has multiple options, determines where they appear on the product page."/> + <field xsi:type="ObjectInputField" name="required_options" type="SortEnum" description="Indicates whether the product has required options."/> + <field xsi:type="ObjectInputField" name="has_options" type="SortEnum" description="Indicates whether additional attributes have been created for the product."/> + <field xsi:type="ObjectInputField" name="image_label" type="SortEnum" description="The label assigned to a product image."/> + <field xsi:type="ObjectInputField" name="small_image_label" type="SortEnum" description="The label assigned to a product's small image."/> + <field xsi:type="ObjectInputField" name="thumbnail_label" type="SortEnum" description="The label assigned to a product's thumbnail image."/> + <field xsi:type="ObjectInputField" name="created_at" type="SortEnum" description="Timestamp indicating when the product was created"/> + <field xsi:type="ObjectInputField" name="updated_at" type="SortEnum" description="Timestamp indicating when the product was last updated"/> + <field xsi:type="ObjectInputField" name="country_of_manufacture" type="SortEnum" description="The product's country of origin"/> + <field xsi:type="ObjectInputField" name="custom_layout" type="SortEnum" description="The name of a custom layout."/> + <field xsi:type="ObjectInputField" name="gift_message_available" type="SortEnum" description="Indicates whether a gift message is available."/> + </type> + <type xsi:type="OutputType" name="Products"> + <field xsi:type="ObjectArrayOutputField" name="items" itemType="ProductInterface" description="An array of products that match the specified search criteria.."/> + <field xsi:type="ObjectOutputField" name="page_info" type="SearchResultPageInfo" description="An object that includes the `page_info` and `currentPage` values specified in the query"/> + <field xsi:type="ScalarOutputField" name="total_count" type="Int" description="The number of products returned."/> + </type> + <type xsi:type="OutputType" name="MediaGalleryEntry"> + <field xsi:type="ScalarOutputField" name="id" type="Int" description="The identifier assigned to the object"/> + <field xsi:type="ScalarOutputField" name="media_type" type="String" description=" 'image' or 'video'"/> + <field xsi:type="ScalarOutputField" name="label" type="String" description="The the 'alt' text displayed on the UI when the user points to the image"/> + <field xsi:type="ScalarOutputField" name="position" type="Int" description="The media item's position after it has been sorted."/> + <field xsi:type="ScalarOutputField" name="disabled" type="Boolean" description="Whether the image is hidden from view"/> + <field xsi:type="ScalarArrayOutputField" name="types" itemType="String" description="Array of image types. It can have the following values: `image`, `small_image`, `thumbnail`"/> + <field xsi:type="ScalarOutputField" name="file" type="String" description="The path of the image on the server"/> + <field xsi:type="ObjectOutputField" name="content" type="ProductMediaGalleryEntriesContent" description="An array that contains information about images"/> + <field xsi:type="ObjectOutputField" name="video_content" type="ProductMediaGalleryEntriesVideoContent" description="An array that contains information about videos"/> + </type> + <type xsi:type="OutputType" name="ProductMediaGalleryEntriesContent"> + <field xsi:type="ScalarOutputField" name="base64_encoded_data" type="String" description="The image in base64 format"/> + <field xsi:type="ScalarOutputField" name="type" type="String" description="The MIME type of the file, such as 'image/png'"/> + <field xsi:type="ScalarOutputField" name="name" type="String" description="The file name of the image"/> + </type> + <type xsi:type="OutputType" name="ProductMediaGalleryEntriesVideoContent"> + <field xsi:type="ScalarOutputField" name="media_type" type="String" description="Must be 'external-video"/> + <field xsi:type="ScalarOutputField" name="video_provider" type="String" description="Describes the video source"/> + <field xsi:type="ScalarOutputField" name="video_url" type="String" description="The URL to the video"/> + <field xsi:type="ScalarOutputField" name="video_title" type="String" description="The title of the video"/> + <field xsi:type="ScalarOutputField" name="video_description" type="String" description="A description of the video"/> + <field xsi:type="ScalarOutputField" name="video_metadata" type="String" description="Optional data about the video"/> + </type> + <type xsi:type="OutputType" name="CustomizableFieldOption"> + <implements interface="CustomizableOptionInterface" copyFields="true"/> + <field xsi:type="ObjectOutputField" name="value" type="CustomizableFieldValue" description="An object that defines a text field."/> + <field xsi:type="ScalarOutputField" name="product_sku" type="String" description="The Stock Keeping Unit of the base product"/> + </type> + <type xsi:type="OutputType" name="CustomizableFileOption"> + <implements interface="CustomizableOptionInterface" copyFields="true"/> + <field xsi:type="ObjectOutputField" name="value" type="CustomizableFileValue" description="An object that defines a file value."/> + <field xsi:type="ScalarOutputField" name="product_sku" type="String" description="The Stock Keeping Unit of the base product"/> + </type> + <type xsi:type="OutputType" name="CustomizableDateOption"> + <implements interface="CustomizableOptionInterface" copyFields="true"/> + <field xsi:type="ObjectOutputField" name="value" type="CustomizableDateValue" description="An object that defines a date field in a customizable option."/> + <field xsi:type="ScalarOutputField" name="product_sku" type="String" description="The Stock Keeping Unit of the base product"/> + </type> + <type xsi:type="OutputType" name="CustomizableDropDownOption"> + <implements interface="CustomizableOptionInterface" copyFields="true"/> + <field xsi:type="ObjectArrayOutputField" name="value" itemType="CustomizableDropDownValue" description="An array that defines the set of options for a drop down menu."/> + </type> + <type xsi:type="OutputType" name="CustomizableRadioOption"> + <implements interface="CustomizableOptionInterface" copyFields="true"/> + <field xsi:type="ObjectArrayOutputField" name="value" itemType="CustomizableRadioValue" description="An array that defines a set of radio buttons."/> + </type> + <type xsi:type="OutputType" name="CustomizableAreaOption"> + <implements interface="CustomizableOptionInterface" copyFields="true"/> + <field xsi:type="ObjectOutputField" name="value" type="CustomizableAreaValue" description="An object that defines a text area."/> + <field xsi:type="ScalarOutputField" name="product_sku" type="String" description="The Stock Keeping Unit of the base product"/> + </type> + <type xsi:type="OutputType" name="CustomizableFieldValue"> + <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price of the custom value."/> + <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="FIXED, PERCENT, or DYNAMIC"/> + <field xsi:type="ScalarOutputField" name="sku" type="String" description="The Stock Keeping Unit for this option"/> + <field xsi:type="ScalarOutputField" name="max_characters" type="Int" description="The maximum number of characters that can be entered for this customizable option"/> + </type> + <type xsi:type="OutputType" name="CustomizableFileValue"> + <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price assigned to this option"/> + <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="FIXED, PERCENT, or DYNAMIC"/> + <field xsi:type="ScalarOutputField" name="sku" type="String" description="The Stock Keeping Unit for this option"/> + <field xsi:type="ScalarOutputField" name="file_extension" type="String" description="The file extension to accept"/> + <field xsi:type="ScalarOutputField" name="image_size_x" type="Int" description="The maximum width of an image"/> + <field xsi:type="ScalarOutputField" name="image_size_y" type="Int" description="The maximum height of an image"/> + </type> + <type xsi:type="OutputType" name="CustomizableDateValue"> + <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price assigned to this option"/> + <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="FIXED, PERCENT, or DYNAMIC"/> + <field xsi:type="ScalarOutputField" name="sku" type="String" description="The Stock Keeping Unit for this option"/> + </type> + <type xsi:type="OutputType" name="CustomizableDropDownValue"> + <field xsi:type="ScalarOutputField" name="option_type_id" type="Int" description="The ID assigned to the value."/> + <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price assigned to this option"/> + <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="FIXED, PERCENT, or DYNAMIC"/> + <field xsi:type="ScalarOutputField" name="sku" type="String" description="The Stock Keeping Unit for this option"/> + <field xsi:type="ScalarOutputField" name="title" type="String" description="The display name for this option"/> + <field xsi:type="ScalarOutputField" name="sort_order" type="Int" description="The order in which the option is displayed"/> + </type> + <type xsi:type="OutputType" name="CustomizableRadioValue"> + <field xsi:type="ScalarOutputField" name="option_type_id" type="Int" description="The ID assigned to the value."/> + <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price assigned to this option"/> + <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="FIXED, PERCENT, or DYNAMIC"/> + <field xsi:type="ScalarOutputField" name="sku" type="String" description="The Stock Keeping Unit for this option"/> + <field xsi:type="ScalarOutputField" name="title" type="String" description="The display name for this option"/> + <field xsi:type="ScalarOutputField" name="sort_order" type="Int" description="The order in which the option is displayed"/> + </type> + <type xsi:type="OutputType" name="CustomizableAreaValue"> + <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price assigned to this option"/> + <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="FIXED, PERCENT, or DYNAMIC"/> + <field xsi:type="ScalarOutputField" name="sku" type="String" description="The Stock Keeping Unit for this option"/> + <field xsi:type="ScalarOutputField" name="max_characters" type="Int" description="The maximum number of characters that can be entered for this customizable option"/> + </type> + <type xsi:type="Enum" name="PriceTypeEnum"> + <item name="fixed">FIXED</item> + <item name="percent">PERCENT</item> + <item name="dynamic">DYNAMIC</item> + </type> +</config> diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/graphql_config2.xml b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/graphql_config2.xml new file mode 100644 index 0000000000000..938a07bd45805 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/graphql_config2.xml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- + Copyright © Magento, Inc. All rights reserved. + See COPYING.txt for license details. + --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> + <type xsi:type="OutputType" name="Query"> + <field xsi:type="ScalarOutputField" name="mergedField" type="Int" description="test field description" resolver="testResolverPath"> + <argument xsi:type="ScalarArgument" name="mergedArgument" type="String" description="test argument description"/> + </field> + </type> + <type xsi:type="Enum" name="PriceAdjustmentDescriptionEnum"> + <item name="included">INCLUDED</item> + <item name="excluded">EXCLUDED</item> + <item name="mergedItem">MERGEDITEM</item> + </type> + <type xsi:type="OutputType" name="ProductLinks"> + <implements interface="MergedInterface" copyFields="true"/> + </type> + <type xsi:type="OutputInterface" name="MergedInterface" typeResolver="resolverPath"> + <field xsi:type="ScalarOutputField" name="mergedFieldN" type="String" description="The identifier of the linked merged product"/> + </type> +</config> + + diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php new file mode 100644 index 0000000000000..07136f77bc8ed --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php @@ -0,0 +1,205 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +return [ + 'Query' => + [ + 'name' => 'Query', + 'type' => 'graphql_type', + 'fields' => + [ + 'products' => + [ + 'name' => 'products', + 'type' => 'Products', + 'required' => false, + 'resolver' => 'Magento\\Framework\\GraphQlPersistence\\Resolver\\Query\\Resolver', + 'arguments' => + [ + 'search' => + [ + 'type' => 'String', + 'name' => 'search', + 'description' => 'Text to be used in a full text search. If multiple keywords are specified, each keyword is evaluated separately.', + ], + + 'filter' => + [ + 'type' => 'ProductFilterInput', + 'name' => 'filter', + 'description' => 'Defines which search criteria to use to find the desired results. Each filter defines the field or fields to be searched, the condition type, and the search value.', + ], + + 'pageSize' => + [ + 'type' => 'Int', + 'name' => 'pageSize', + 'description' => 'The maximum number of items to return. If no value is specified, the search returns 20 items.', + ], + + 'currentPage' => + [ + 'type' => 'Int', + 'name' => 'currentPage', + 'description' => 'Specifies which page of results to return. If no value is specified, the first page is returned. If you specify a value that is greater than the number of available pages, an error is returned.', + ], + + 'sort' => + [ + 'type' => 'ProductSortInput', + 'name' => 'sort', + 'description' => 'Specifies which field or fields to use for sorting the results. If you specify more than one field, Magento sorts by the first field listed. Then, if any items have the same value, those items will be sorted by the secondary field. The value for each field can be set to either ASC (ascending) or DESC (descending).', + ] + ] + ], + 'mergedField' => + [ + 'name' => 'mergedField', + 'type' => 'Int', + 'required' => false, + 'resolver' => 'testResolverPath', + 'description' => 'test field description', + 'arguments' => + [ + 'mergedArgument' => + [ + 'type' => 'String', + 'name' => 'mergedArgument', + 'description' => 'test argument description', + ] + ] + ] + ] + ], + 'PriceAdjustmentDescriptionEnum' => + [ + 'name' => 'PriceAdjustmentDescriptionEnum', + 'type' => 'graphql_enum', + 'items' => + [ + 'INCLUDED' => + [ + 'name' => 'included', + '_value' => 'INCLUDED', + ], + 'EXCLUDED' => + [ + 'name' => 'excluded', + '_value' => 'EXCLUDED', + ], + 'MERGEDITEM' => + [ + 'name' => 'mergedItem', + '_value' => 'MERGEDITEM', + ], + + ], + ], + 'PriceTypeEnum' => + [ + 'name' => 'PriceTypeEnum', + 'type' => 'graphql_enum', + 'items' => + [ + 'FIXED' => + [ + 'name' => 'fixed', + '_value' => 'FIXED', + ], + 'PERCENT' => + [ + 'name' => 'percent', + '_value' => 'PERCENT', + ], + 'DYNAMIC' => + [ + 'name' => 'dynamic', + '_value' => 'DYNAMIC', + ] + ] + ], + 'ProductLinks' => + [ + 'name' => 'ProductLinks', + 'type' => 'graphql_type', + 'implements' => + [ + 'ProductLinksInterface' => + [ + 'interface' => 'ProductLinksInterface', + 'copyFields' => 'true', + ], + + 'MergedInterface' => + [ + 'interface' => 'MergedInterface', + 'copyFields' => 'true', + ], + ], + 'fields' => + [ + 'sku' => + [ + 'name' => 'sku', + 'type' => 'String', + 'required' => false, + 'description' => 'The identifier of the linked product', + 'arguments' => + [ + ], + ], + 'link_type' => + [ + 'name' => 'link_type', + 'type' => 'String', + 'required' => false, + 'description' => 'One of \'related\', \'associated\', \'upsell\', or \'crosssell\'.', + 'arguments' => + [ + ], + ], + 'linked_product_sku' => + [ + 'name' => 'linked_product_sku', + 'type' => 'String', + 'required' => false, + 'description' => 'The SKU of the linked product', + 'arguments' => + [ + ], + ], + 'linked_product_type' => + [ + 'name' => 'linked_product_type', + 'type' => 'String', + 'required' => false, + 'description' => 'The type of linked product (\'simple\', \'virtual\', \'bundle\', \'downloadable\',\'grouped\', \'configurable\')', + 'arguments' => + [ + ], + ], + 'position' => + [ + 'name' => 'position', + 'type' => 'Int', + 'required' => false, + 'description' => 'The position within the list of product links', + 'arguments' => + [ + ], + ], + 'mergedFieldN' => + [ + 'name' => 'mergedFieldN', + 'type' => 'String', + 'required' => false, + 'description' => 'The identifier of the linked merged product', + 'arguments' => + [ + ], + ], + ], + ] +]; From 7b90a94036b16ad90949700e59095e8e49dad833 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@magento.com> Date: Mon, 12 Mar 2018 17:25:01 -0500 Subject: [PATCH 054/668] MAGETWO-89178: Create integration or functional test - additional test scenario for graphql xsd validation --- .../Model/Config/_files/invalidGraphQlXmlArray.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/code/Magento/GraphQl/Test/Unit/Model/Config/_files/invalidGraphQlXmlArray.php b/app/code/Magento/GraphQl/Test/Unit/Model/Config/_files/invalidGraphQlXmlArray.php index fa4f4b204727e..8c068bcb2badb 100644 --- a/app/code/Magento/GraphQl/Test/Unit/Model/Config/_files/invalidGraphQlXmlArray.php +++ b/app/code/Magento/GraphQl/Test/Unit/Model/Config/_files/invalidGraphQlXmlArray.php @@ -4,6 +4,19 @@ * See COPYING.txt for license details. */ return [ + 'character_data_between_type_elements' => [ + '<?xml version="1.0"?><config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <type xsi:type="OutputInterface" name="CustomizableOptionInterface" + typeResolver="Magento\CatalogGraphQl\Model\CustomizableOptionTypeResolver"> + <field xsi:type="ScalarOutputField" name="title" type="String" description="The displayed name of the option"/> + </type>Hello + <type xsi:type="OutputType" name="VirtualProduct"> + <implements interface="CustomizableProductInterface" copyFields="true"/> + </type></config>', + [ + + ], + ], 'type_InputType_with_invalid_attribute' => [ '<?xml version="1.0"?><config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <type xsi:type ="InputType" name="someInput" summary ="summary"></type></config>', From aa3179d0d04c3aeb76bcc42bae7f422ab877b7ac Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Mon, 12 Mar 2018 17:31:20 -0500 Subject: [PATCH 055/668] MAGETWO-89031: Make all graphql methods to return strict type - making usage of direct dependency of webonyx strict types without breaking our factories --- .../Framework/GraphQl/SchemaProvider.php | 17 +++++- .../GraphQl/Type/Definition/ScalarTypes.php | 61 ++++++++----------- .../GraphQl/Type/Input/InputMapper.php | 44 +++++++++---- .../GraphQl/Type/Input/InputObjectType.php | 35 +++++++++-- .../Output/ElementMapper/Formatter/Fields.php | 25 +++++++- .../GraphQl/Type/Output/OutputMapper.php | 15 ++--- .../Magento/Framework/GraphQl/Type/Schema.php | 45 -------------- .../Magento/Framework/GraphQl/TypeFactory.php | 29 --------- 8 files changed, 128 insertions(+), 143 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php b/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php index a5343293fdd36..083e25e236684 100644 --- a/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php +++ b/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php @@ -10,6 +10,7 @@ use Magento\Framework\GraphQl\Type\Definition\OutputType; use Magento\Framework\GraphQl\Config\ConfigInterface; use Magento\Framework\GraphQl\Type\Output\OutputMapper; +use Magento\Framework\GraphQl\Type\Definition\ScalarTypes; /** * Container for retrieving generated type object representations of a GraphQL Schema. @@ -26,17 +27,25 @@ class SchemaProvider */ private $outputMapper; + /** + * @var ScalarTypes + */ + private $scalarTypes; + /** * SchemaProvider constructor. * @param ConfigInterface $config * @param OutputMapper $outputMapper + * @param ScalarTypes $scalarTypes */ public function __construct( ConfigInterface $config, - OutputMapper $outputMapper + OutputMapper $outputMapper, + ScalarTypes $scalarTypes ) { $this->config = $config; $this->outputMapper = $outputMapper; + $this->scalarTypes = $scalarTypes; } /** @@ -48,7 +57,11 @@ public function getTypes() : array { $types = []; foreach ($this->config->getDeclaredTypeNames() as $typeName) { - $types[$typeName] = $this->outputMapper->getTypeObject($typeName); + if ($this->scalarTypes->hasScalarTypeClass($typeName)) { + $types[$typeName] = $this->scalarTypes->getScalarTypeInstance($typeName); + } else { + $types[$typeName] = $this->outputMapper->getTypeObject($typeName); + } } return $types; } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php index 0531c4eae3387..e272432d7a556 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php @@ -12,61 +12,50 @@ */ class ScalarTypes { - /** - * @var string[] - */ - private $scalarTypes = [ - 'Boolean' => BooleanType::class, - 'Float' => FloatType::class, - 'ID' => IdType::class, - 'Int' => IntType::class, - 'String' => StringType::class - ]; - - /** - * @var TypeInterface - */ - private $scalarTypesInstances = [ - - ]; - /** * @param string $typeName * @return bool */ public function hasScalarTypeClass(string $typeName) : bool { - return isset($this->scalarTypes[$typeName]) ? true : false; + $internalTypes = \GraphQL\Type\Definition\Type::getInternalTypes(); + return isset($internalTypes[$typeName]) ? true : false; } /** * @param string $typeName - * @return string|null + * @return \GraphQL\Type\Definition\ScalarType * @throws \LogicException */ - public function getScalarTypeClass(string $typeName) : string + public function getScalarTypeInstance(string $typeName) : \GraphQL\Type\Definition\ScalarType { + $internalTypes = \GraphQL\Type\Definition\Type::getInternalTypes(); if ($this->hasScalarTypeClass($typeName)) { - return $this->scalarTypes[$typeName]; + return $internalTypes[$typeName]; + } else { + throw new \LogicException(sprintf('Scalar type %s doesn\'t exist', $typeName)); } - throw new \LogicException(sprintf('Scalar type class with name %s doesn\'t exist', $typeName)); } /** - * @param string $typeName - * @return TypeInterface|null - * @throws \LogicException + * Create an list array type + * + * @param \GraphQL\Type\Definition\ScalarType $definedType + * @return ListOfType */ - public function getScalarTypeInstance(string $typeName) : TypeInterface + public function createList(\GraphQL\Type\Definition\ScalarType $definedType) : ListOfType { - if ($this->hasScalarTypeClass($typeName)) { - if (!isset($this->scalarTypesInstances[$typeName])) { - $scalarClassName = $this->getScalarTypeClass($typeName); - $this->scalarTypesInstances[$typeName] = new $scalarClassName(); - } - return $this->scalarTypesInstances[$typeName]; - } else { - throw new \LogicException(sprintf('Scalar type %s doesn\'t exist', $typeName)); - } + return new ListOfType($definedType); + } + + /** + * Create a non null type + * + * @param \GraphQL\Type\Definition\ScalarType $definedType + * @return NonNull + */ + public function createNonNull(\GraphQL\Type\Definition\ScalarType $definedType) : NonNull + { + return new NonNull($definedType); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php index 67428dbb10213..2325fc7fe485e 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php @@ -11,6 +11,7 @@ use Magento\Framework\GraphQl\Config\Data\Argument; use Magento\Framework\GraphQl\Type\Definition\InputType; use Magento\Framework\GraphQl\TypeFactory; +use Magento\Framework\GraphQl\Type\Definition\ScalarTypes; /** * Class OutputMapper @@ -32,19 +33,27 @@ class InputMapper */ private $typeFactory; + /** + * @var ScalarTypes + */ + private $scalarTypes; + /** * @param InputFactory $inputFactory * @param ConfigInterface $config * @param TypeFactory $typeFactory + * @param ScalarTypes $scalarTypes */ public function __construct( InputFactory $inputFactory, ConfigInterface $config, - TypeFactory $typeFactory + TypeFactory $typeFactory, + ScalarTypes $scalarTypes ) { $this->inputFactory = $inputFactory; $this->config = $config; $this->typeFactory = $typeFactory; + $this->scalarTypes = $scalarTypes; } /** @@ -56,20 +65,31 @@ public function __construct( public function getRepresentation(Argument $argument) : array { $type = $argument->getType(); - $instance = $this->typeFactory->getScalar($type); $calculateDefault = true; - if (!$instance) { + if ($this->scalarTypes->hasScalarTypeClass($type)) { + $instance = $this->scalarTypes->getScalarTypeInstance($type); + if ($argument->isList()) { + $instance = $argument->areItemsRequired() ? $this->scalarTypes->createNonNull($instance) : $instance; + $instance = $this->scalarTypes->createList($instance); + } + if ($argument->isRequired()) { + $instance = $this->scalarTypes->createNonNull($instance); + } + } else { $configElement = $this->config->getTypeStructure($type); $instance = $this->inputFactory->create($configElement); $calculateDefault = false; + if ($argument->isList()) { + $instance = $argument->areItemsRequired() ? $this->typeFactory->createNonNull($instance) : $instance; + $instance = $this->typeFactory->createList($instance); + } + if ($argument->isRequired()) { + $instance = $this->typeFactory->createNonNull($instance); + } } - if ($argument->isList()) { - $instance = $argument->areItemsRequired() ? $this->typeFactory->createNonNull($instance) : $instance; - $instance = $this->typeFactory->createList($instance); - } $calculatedArgument = [ - 'type' => $argument->isRequired() ? $this->typeFactory->createNonNull($instance) : $instance, + 'type' => $instance, 'description' => $argument->getDescription() ]; @@ -100,11 +120,11 @@ public function getRepresentation(Argument $argument) : array */ public function getFieldRepresentation(string $type) : InputType { - $instance = $this->typeFactory->getScalar($type); - if (!$instance) { + if ($this->scalarTypes->hasScalarTypeClass($type)) { + return $this->scalarTypes->getScalarTypeInstance($type); + } else { $configElement = $this->config->getTypeStructure($type); - $instance = $this->inputFactory->create($configElement); + return $this->inputFactory->create($configElement); } - return $instance; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php index ce264f9dc0a6c..15821e598b70b 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php @@ -12,6 +12,7 @@ use Magento\Framework\GraphQl\Config\Data\Type as TypeStructure; use Magento\Framework\GraphQl\Type\Definition\TypeInterface; use Magento\Framework\GraphQl\TypeFactory; +use Magento\Framework\GraphQl\Type\Definition\ScalarTypes; /** * Class InputObjectType @@ -23,25 +24,47 @@ class InputObjectType extends \Magento\Framework\GraphQl\Type\Definition\InputOb */ private $typeFactory; + /** + * @var ScalarTypes + */ + private $scalarTypes; + + /** + * @param InputMapper $inputMapper + * @param TypeStructure $structure + * @param TypeFactory $typeFactory + * @param ScalarTypes $scalarTypes + */ public function __construct( InputMapper $inputMapper, TypeStructure $structure, - TypeFactory $typeFactory + TypeFactory $typeFactory, + ScalarTypes $scalarTypes ) { $this->typeFactory = $typeFactory; + $this->scalarTypes = $scalarTypes; $config = [ 'name' => $structure->getName(), 'description' => $structure->getDescription() ]; foreach ($structure->getFields() as $field) { - if ($field->getType() == $structure->getName()) { - $type = $this; + if ($this->scalarTypes->hasScalarTypeClass($field->getType())) { + $type = $this->scalarTypes->getScalarTypeInstance($field->getType()); + if ($field->isList()) { + $type = $this->scalarTypes->createList($type); + } + if ($field->isRequired()) { + $type = $this->scalarTypes->createNonNull($type); + } } else { - $type = $inputMapper->getFieldRepresentation($field->getType()); + if ($field->getType() == $structure->getName()) { + $type = $this; + } else { + $type = $inputMapper->getFieldRepresentation($field->getType()); + } + $type = $this->processIsNullable($field, $this->processIsList($field, $type)); } - $type = $this->processIsNullable($field, $this->processIsList($field, $type)); - $config['fields'][$field->getName()] = [ 'name' => $field->getName(), 'type' => $type diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php index 551e7b803795b..7648913297c9d 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php @@ -19,6 +19,7 @@ use Magento\Framework\GraphQl\Type\Definition\TypeInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\GraphQl\Config\FieldConfig; +use Magento\Framework\GraphQl\Type\Definition\ScalarTypes; /** * Formats all fields configured for given type structure, if any. @@ -55,6 +56,11 @@ class Fields implements FormatterInterface */ private $typeFactory; + /** + * @var ScalarTypes + */ + private $scalarTypes; + /** * @param ObjectManagerInterface $objectManager * @param FieldConfig $fieldConfig @@ -62,6 +68,7 @@ class Fields implements FormatterInterface * @param OutputMapper $outputMapper * @param InputMapper $inputMapper * @param TypeFactory $typeFactory + * @param ScalarTypes $scalarTypes */ public function __construct( ObjectManagerInterface $objectManager, @@ -69,7 +76,8 @@ public function __construct( ArgumentFactory $argumentFactory, OutputMapper $outputMapper, InputMapper $inputMapper, - TypeFactory $typeFactory + TypeFactory $typeFactory, + ScalarTypes $scalarTypes ) { $this->objectManager = $objectManager; $this->fieldConfig = $fieldConfig; @@ -77,6 +85,7 @@ public function __construct( $this->outputMapper = $outputMapper; $this->inputMapper = $inputMapper; $this->typeFactory = $typeFactory; + $this->scalarTypes = $scalarTypes; } /** @@ -88,7 +97,19 @@ public function format(StructureInterface $typeStructure, OutputType $outputType $config = []; /** @var Field $field */ foreach ($typeStructure->getFields() as $field) { - $type = $this->getFieldType($typeStructure, $field, $outputType); + if ($typeStructure->getName() == $field->getType()) { + $type = $outputType; + } elseif ($this->scalarTypes->hasScalarTypeClass($field->getType())) { + if ($field->isList()) { + $type = new \Magento\Framework\GraphQl\Type\Definition\ListOfType( + $this->scalarTypes->getScalarTypeInstance($field->getType()) + ); + } else { + $type = $this->scalarTypes->getScalarTypeInstance($field->getType()); + } + } else { + $type = $this->getFieldType($typeStructure, $field, $outputType); + } $config['fields'][$field->getName()] = [ 'name' => $field->getName(), 'type' => $type, diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php index a499892791e01..44986663c3614 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php @@ -54,12 +54,8 @@ public function __construct( */ public function getTypeObject(string $type) : OutputType { - $instance = $this->typeFactory->getScalar($type); - if (!$instance) { - $configElement = $this->config->getTypeStructure($type); - $instance = $this->outputFactory->create($configElement); - } - return $instance; + $configElement = $this->config->getTypeStructure($type); + return $this->outputFactory->create($configElement); } /** @@ -70,11 +66,8 @@ public function getTypeObject(string $type) : OutputType */ public function getInterface(string $type) : ?OutputInterfaceObject { - $instance = $this->typeFactory->getScalar($type); - if (!$instance) { - $configElement = $this->config->getTypeStructure($type); - $instance = $this->outputFactory->create($configElement); - } + $configElement = $this->config->getTypeStructure($type); + $instance = $this->outputFactory->create($configElement); if ($instance instanceof OutputInterfaceObject) { return $instance; } else { diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Schema.php b/lib/internal/Magento/Framework/GraphQl/Type/Schema.php index e588f77785e8f..6d29359af60c3 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Schema.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Schema.php @@ -12,50 +12,5 @@ */ class Schema extends \GraphQL\Type\Schema { - /** - * @api - * @param array|\GraphQL\Type\SchemaConfig $config - */ - public function __construct($config) - { - $config = $this->replaceScalarTypes($config); - parent::__construct($config); - } - /** - * Replace wrappers for scalar types with webonyx scalar types to prevent creation of two scalar types. - * - * Note that webonyx will try to inject it's own scalar types and because wrappers have the same name - * Example: String vs String - webonyx will trigger an exception. - * - * @param array $config - * @return array - */ - private function replaceScalarTypes(array $config) : array - { - $recur = function (&$value) use (&$recur) { - if ($value instanceof \GraphQL\Type\Definition\ObjectType) { - /** @var \Magento\Framework\GraphQl\Type\Definition\ObjectType $value */ - $fields = $value->getFields(); - array_walk_recursive($fields, $recur); - } elseif ($value instanceof \Graphql\Type\Definition\FieldDefinition) { - /** @var \Graphql\Type\Definition\FieldDefinition $value */ - if ($value->config['type'] instanceof \Magento\Framework\GraphQl\Type\Definition\StringType) { - $value->config['type'] = \GraphQL\Type\Definition\Type::string(); - } elseif ($value->config['type'] instanceof \Magento\Framework\GraphQl\Type\Definition\IDType) { - $value->config['type'] = \GraphQL\Type\Definition\Type::id(); - } elseif ($value->config['type'] instanceof \Magento\Framework\GraphQl\Type\Definition\FloatType) { - $value->config['type'] = \GraphQL\Type\Definition\Type::float(); - } elseif ($value->config['type'] instanceof \Magento\Framework\GraphQl\Type\Definition\IntType) { - $value->config['type'] = \GraphQL\Type\Definition\Type::int(); - } elseif ($value->config['type'] instanceof \Magento\Framework\GraphQl\Type\Definition\BooleanType) { - $value->config['type'] = \GraphQL\Type\Definition\Type::boolean(); - } - } - }; - - array_walk_recursive($config, $recur); - - return $config; - } } diff --git a/lib/internal/Magento/Framework/GraphQl/TypeFactory.php b/lib/internal/Magento/Framework/GraphQl/TypeFactory.php index a38a00fda463d..a4d72f56f9253 100644 --- a/lib/internal/Magento/Framework/GraphQl/TypeFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/TypeFactory.php @@ -14,41 +14,12 @@ use Magento\Framework\GraphQl\Type\Definition\ListOfType; use Magento\Framework\GraphQl\Type\Definition\NonNull; use Magento\Framework\GraphQl\Type\Definition\TypeInterface; -use Magento\Framework\GraphQl\Type\Definition\ScalarTypes; /** * Factory for @see TypeInterface implementations */ class TypeFactory { - /** - * @var ScalarTypes - */ - private $scalarTypes; - - /** - * TypeFactory constructor. - * @param ScalarTypes $scalarTypes - */ - public function __construct(ScalarTypes $scalarTypes) - { - $this->scalarTypes = $scalarTypes; - } - - /** - * Get instance of a scalar type as singleton - * - * @param string $type - * @return TypeInterface|null - */ - public function getScalar(string $type) : ?TypeInterface - { - if ($this->scalarTypes->hasScalarTypeClass($type)) { - return $this->scalarTypes->getScalarTypeInstance($type); - } - return null; - } - /** * Create an object type * From 1fee07b0aee809372bf33673650699e7fe463b8b Mon Sep 17 00:00:00 2001 From: Mohammad HAJ SALEM <haj-salem@e-conomix.at> Date: Tue, 13 Mar 2018 08:46:14 +0100 Subject: [PATCH 056/668] :heavy_minus_sign: remove duplication of webonyx/graphql-php --- composer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 62858294ae0e0..95f6dea8a55fb 100644 --- a/composer.json +++ b/composer.json @@ -75,8 +75,7 @@ "zendframework/zend-text": "^2.6.0", "zendframework/zend-uri": "^2.5.1", "zendframework/zend-validator": "^2.6.0", - "zendframework/zend-view": "^2.10.0", - "webonyx/graphql-php": "^0.11.1" + "zendframework/zend-view": "^2.10.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "~2.1.1", From 3cd120838b2553ef4e7ee239d3fe726e09fffef0 Mon Sep 17 00:00:00 2001 From: Mohammad HAJ SALEM <haj-salem@e-conomix.at> Date: Tue, 13 Mar 2018 08:50:22 +0100 Subject: [PATCH 057/668] :rocket: update dependancies Update zendframework/zend-mvc 2.6.3 => 2.7.0 --- lib/internal/Magento/Framework/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json index b442effe5ffda..e1123801c221d 100644 --- a/lib/internal/Magento/Framework/composer.json +++ b/lib/internal/Magento/Framework/composer.json @@ -34,7 +34,7 @@ "zendframework/zend-code": "^3.1.0", "zendframework/zend-crypt": "^2.6.0", "zendframework/zend-http": "^2.6.0", - "zendframework/zend-mvc": "~2.6.3", + "zendframework/zend-mvc": "~2.7.0", "zendframework/zend-stdlib": "^2.7.7", "zendframework/zend-uri": "^2.5.1", "zendframework/zend-validator": "^2.6.0" From 73482be56a209e55e2e53c96563a9b52a98f9b77 Mon Sep 17 00:00:00 2001 From: Mohammad HAJ SALEM <haj-salem@e-conomix.at> Date: Tue, 13 Mar 2018 09:02:16 +0100 Subject: [PATCH 058/668] :rocket: update dependancies --- composer.lock | 6388 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 6388 insertions(+) create mode 100644 composer.lock diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000000000..300f95d37374c --- /dev/null +++ b/composer.lock @@ -0,0 +1,6388 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "29977708b816625e70177283e2df0d74", + "packages": [ + { + "name": "braintree/braintree_php", + "version": "3.22.0", + "source": { + "type": "git", + "url": "https://github.com/braintree/braintree_php.git", + "reference": "402617b803779bed5ae899209afa75ef9950becc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/braintree/braintree_php/zipball/402617b803779bed5ae899209afa75ef9950becc", + "reference": "402617b803779bed5ae899209afa75ef9950becc", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-dom": "*", + "ext-hash": "*", + "ext-openssl": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "autoload": { + "psr-0": { + "Braintree": "lib/" + }, + "psr-4": { + "Braintree\\": "lib/Braintree" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Braintree", + "homepage": "http://www.braintreepayments.com" + } + ], + "description": "Braintree PHP Client Library", + "time": "2017-02-16T19:59:04+00:00" + }, + { + "name": "colinmollenhour/cache-backend-file", + "version": "1.4", + "source": { + "type": "git", + "url": "https://github.com/colinmollenhour/Cm_Cache_Backend_File.git", + "reference": "51251b80a817790eb624fbe2afc882c14f3c4fb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_File/zipball/51251b80a817790eb624fbe2afc882c14f3c4fb0", + "reference": "51251b80a817790eb624fbe2afc882c14f3c4fb0", + "shasum": "" + }, + "require": { + "magento-hackathon/magento-composer-installer": "*" + }, + "type": "magento-module", + "autoload": { + "classmap": [ + "File.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin Mollenhour" + } + ], + "description": "The stock Zend_Cache_Backend_File backend has extremely poor performance for cleaning by tags making it become unusable as the number of cached items increases. This backend makes many changes resulting in a huge performance boost, especially for tag cleaning.", + "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_File", + "time": "2016-05-02T16:24:47+00:00" + }, + { + "name": "colinmollenhour/cache-backend-redis", + "version": "1.10.2", + "source": { + "type": "git", + "url": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis.git", + "reference": "18b33e4b69cf15747ab98b4f2c98ab445da05abd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_Redis/zipball/18b33e4b69cf15747ab98b4f2c98ab445da05abd", + "reference": "18b33e4b69cf15747ab98b4f2c98ab445da05abd", + "shasum": "" + }, + "require": { + "magento-hackathon/magento-composer-installer": "*" + }, + "type": "magento-module", + "autoload": { + "classmap": [ + "Cm/Cache/Backend/Redis.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin Mollenhour" + } + ], + "description": "Zend_Cache backend using Redis with full support for tags.", + "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis", + "time": "2017-03-25T04:54:24+00:00" + }, + { + "name": "colinmollenhour/credis", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/colinmollenhour/credis.git", + "reference": "049ccfb2c680e4dfa6adcfa97f2f29d086919abd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/049ccfb2c680e4dfa6adcfa97f2f29d086919abd", + "reference": "049ccfb2c680e4dfa6adcfa97f2f29d086919abd", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "Client.php", + "Cluster.php", + "Sentinel.php", + "Module.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Colin Mollenhour", + "email": "colin@mollenhour.com" + } + ], + "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", + "homepage": "https://github.com/colinmollenhour/credis", + "time": "2017-10-05T20:28:58+00:00" + }, + { + "name": "colinmollenhour/php-redis-session-abstract", + "version": "v1.3.8", + "source": { + "type": "git", + "url": "https://github.com/colinmollenhour/php-redis-session-abstract.git", + "reference": "9f69f5c1be512d5ff168e731e7fa29ab2905d847" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/colinmollenhour/php-redis-session-abstract/zipball/9f69f5c1be512d5ff168e731e7fa29ab2905d847", + "reference": "9f69f5c1be512d5ff168e731e7fa29ab2905d847", + "shasum": "" + }, + "require": { + "colinmollenhour/credis": "~1.6", + "php": "~5.5.0|~5.6.0|~7.0.0|~7.1.0|~7.2.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "Cm\\RedisSession\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin Mollenhour" + } + ], + "description": "A Redis-based session handler with optimistic locking", + "homepage": "https://github.com/colinmollenhour/php-redis-session-abstract", + "time": "2018-01-08T14:53:13+00:00" + }, + { + "name": "composer/ca-bundle", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "943b2c4fcad1ef178d16a713c2468bf7e579c288" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/943b2c4fcad1ef178d16a713c2468bf7e579c288", + "reference": "943b2c4fcad1ef178d16a713c2468bf7e579c288", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35", + "psr/log": "^1.0", + "symfony/process": "^2.5 || ^3.0 || ^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "time": "2017-11-29T09:37:33+00:00" + }, + { + "name": "composer/composer", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "7ee2a5e1cf32e9c8439445fe8dce2c046c2abebd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/7ee2a5e1cf32e9c8439445fe8dce2c046c2abebd", + "reference": "7ee2a5e1cf32e9c8439445fe8dce2c046c2abebd", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "composer/semver": "^1.0", + "composer/spdx-licenses": "^1.0", + "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0", + "seld/cli-prompt": "^1.0", + "seld/jsonlint": "^1.4", + "seld/phar-utils": "^1.0", + "symfony/console": "^2.7 || ^3.0", + "symfony/filesystem": "^2.7 || ^3.0", + "symfony/finder": "^2.7 || ^3.0", + "symfony/process": "^2.7 || ^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "^2.3 || ^3.0" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\": "src/Composer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "time": "2017-03-10T08:29:45+00:00" + }, + { + "name": "composer/semver", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2016-08-30T16:08:34+00:00" + }, + { + "name": "composer/spdx-licenses", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "7e111c50db92fa2ced140f5ba23b4e261bc77a30" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7e111c50db92fa2ced140f5ba23b4e261bc77a30", + "reference": "7e111c50db92fa2ced140f5ba23b4e261bc77a30", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "time": "2018-01-31T13:17:27+00:00" + }, + { + "name": "container-interop/container-interop", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/container-interop/container-interop.git", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "shasum": "" + }, + "require": { + "psr/container": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Interop\\Container\\": "src/Interop/Container/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", + "homepage": "https://github.com/container-interop/container-interop", + "time": "2017-02-14T19:40:03+00:00" + }, + { + "name": "justinrainbow/json-schema", + "version": "5.2.7", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "8560d4314577199ba51bf2032f02cd1315587c23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/8560d4314577199ba51bf2032f02cd1315587c23", + "reference": "8560d4314577199ba51bf2032f02cd1315587c23", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.35" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "time": "2018-02-14T22:26:30+00:00" + }, + { + "name": "magento/composer", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/magento/composer.git", + "reference": "130753af2b755f1967e253deb661225942bb302c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/magento/composer/zipball/130753af2b755f1967e253deb661225942bb302c", + "reference": "130753af2b755f1967e253deb661225942bb302c", + "shasum": "" + }, + "require": { + "composer/composer": "1.4.1", + "php": "~5.5.0|~5.6.0|~7.0.0|~7.1.0", + "symfony/console": "~2.3, !=2.7.0" + }, + "require-dev": { + "phpunit/phpunit": "4.1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Magento\\Composer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "Magento composer library helps to instantiate Composer application and run composer commands.", + "time": "2017-04-24T09:57:02+00:00" + }, + { + "name": "magento/magento-composer-installer", + "version": "0.1.13", + "source": { + "type": "git", + "url": "https://github.com/magento/magento-composer-installer.git", + "reference": "8b6c32f53b4944a5d6656e86344cd0f9784709a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/magento/magento-composer-installer/zipball/8b6c32f53b4944a5d6656e86344cd0f9784709a1", + "reference": "8b6c32f53b4944a5d6656e86344cd0f9784709a1", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0" + }, + "replace": { + "magento-hackathon/magento-composer-installer": "*" + }, + "require-dev": { + "composer/composer": "*@dev", + "firegento/phpcs": "dev-patch-1", + "mikey179/vfsstream": "*", + "phpunit/phpunit": "*", + "phpunit/phpunit-mock-objects": "dev-master", + "squizlabs/php_codesniffer": "1.4.7", + "symfony/process": "*" + }, + "type": "composer-plugin", + "extra": { + "composer-command-registry": [ + "MagentoHackathon\\Composer\\Magento\\Command\\DeployCommand" + ], + "class": "MagentoHackathon\\Composer\\Magento\\Plugin" + }, + "autoload": { + "psr-0": { + "MagentoHackathon\\Composer\\Magento": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Vinai Kopp", + "email": "vinai@netzarbeiter.com" + }, + { + "name": "Daniel Fahlke aka Flyingmana", + "email": "flyingmana@googlemail.com" + }, + { + "name": "Jörg Weller", + "email": "weller@flagbit.de" + }, + { + "name": "Karl Spies", + "email": "karl.spies@gmx.net" + }, + { + "name": "Tobias Vogt", + "email": "tobi@webguys.de" + }, + { + "name": "David Fuhr", + "email": "fuhr@flagbit.de" + } + ], + "description": "Composer installer for Magento modules", + "homepage": "https://github.com/magento/magento-composer-installer", + "keywords": [ + "composer-installer", + "magento" + ], + "time": "2017-12-29T16:45:24+00:00" + }, + { + "name": "magento/zendframework1", + "version": "1.13.1", + "source": { + "type": "git", + "url": "https://github.com/magento/zf1.git", + "reference": "e2693f047bb7ccb8affa8f72ea40269f4c9f4fbf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/magento/zf1/zipball/e2693f047bb7ccb8affa8f72ea40269f4c9f4fbf", + "reference": "e2693f047bb7ccb8affa8f72ea40269f4c9f4fbf", + "shasum": "" + }, + "require": { + "php": ">=5.2.11" + }, + "require-dev": { + "phpunit/dbunit": "1.3.*", + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.12.x-dev" + } + }, + "autoload": { + "psr-0": { + "Zend_": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "library/" + ], + "license": [ + "BSD-3-Clause" + ], + "description": "Magento Zend Framework 1", + "homepage": "http://framework.zend.com/", + "keywords": [ + "ZF1", + "framework" + ], + "time": "2017-06-21T14:56:23+00:00" + }, + { + "name": "monolog/monolog", + "version": "1.23.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "jakub-onderka/php-parallel-lint": "0.9", + "php-amqplib/php-amqplib": "~2.4", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "ruflin/elastica": ">=0.90 <3.0", + "sentry/sentry": "^0.13", + "swiftmailer/swiftmailer": "^5.3|^6.0" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server", + "sentry/sentry": "Allow sending log messages to a Sentry server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "time": "2017-06-19T01:22:40+00:00" + }, + { + "name": "oyejorge/less.php", + "version": "v1.7.0.14", + "source": { + "type": "git", + "url": "https://github.com/oyejorge/less.php.git", + "reference": "42925c5a01a07d67ca7e82dfc8fb31814d557bc9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/oyejorge/less.php/zipball/42925c5a01a07d67ca7e82dfc8fb31814d557bc9", + "reference": "42925c5a01a07d67ca7e82dfc8fb31814d557bc9", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.24" + }, + "bin": [ + "bin/lessc" + ], + "type": "library", + "autoload": { + "psr-0": { + "Less": "lib/" + }, + "classmap": [ + "lessc.inc.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Matt Agar", + "homepage": "https://github.com/agar" + }, + { + "name": "Martin Jantošovič", + "homepage": "https://github.com/Mordred" + }, + { + "name": "Josh Schmidt", + "homepage": "https://github.com/oyejorge" + } + ], + "description": "PHP port of the Javascript version of LESS http://lesscss.org (Originally maintained by Josh Schmidt)", + "homepage": "http://lessphp.gpeasy.com", + "keywords": [ + "css", + "less", + "less.js", + "lesscss", + "php", + "stylesheet" + ], + "time": "2017-03-28T22:19:25+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v2.0.11", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8", + "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ], + "time": "2017-09-27T21:40:39+00:00" + }, + { + "name": "pelago/emogrifier", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/MyIntervals/emogrifier.git", + "reference": "8babf8ddbf348f26b29674e2f84db66ff7e3d95e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/8babf8ddbf348f26b29674e2f84db66ff7e3d95e", + "reference": "8babf8ddbf348f26b29674e2f84db66ff7e3d95e", + "shasum": "" + }, + "require": { + "php": "^5.5.0 || ~7.0.0 || ~7.1.0 || ~7.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.0", + "squizlabs/php_codesniffer": "^3.1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Pelago\\": "Classes/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Reeve", + "email": "jreeve@pelagodesign.com" + }, + { + "name": "Cameron Brooks" + }, + { + "name": "Jaime Prado" + }, + { + "name": "Roman Ožana", + "email": "ozana@omdesign.cz" + }, + { + "name": "Oliver Klee", + "email": "github@oliverklee.de" + }, + { + "name": "Zoli Szabó", + "email": "zoli.szabo+github@gmail.com" + } + ], + "description": "Converts CSS styles into inline style attributes in your HTML code", + "homepage": "https://www.myintervals.com/emogrifier.php", + "keywords": [ + "css", + "email", + "pre-processing" + ], + "time": "2018-01-05T23:30:21+00:00" + }, + { + "name": "phpseclib/phpseclib", + "version": "2.0.10", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "d305b780829ea4252ed9400b3f5937c2c99b51d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/d305b780829ea4252ed9400b3f5937c2c99b51d4", + "reference": "d305b780829ea4252ed9400b3f5937c2c99b51d4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phing/phing": "~2.7", + "phpunit/phpunit": "^4.8.35|^5.7|^6.0", + "sami/sami": "~2.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "suggest": { + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "time": "2018-02-19T04:29:13+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2016-10-10T12:19:37+00:00" + }, + { + "name": "ramsey/uuid", + "version": "3.6.1", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "4ae32dd9ab8860a4bbd750ad269cba7f06f7934e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/4ae32dd9ab8860a4bbd750ad269cba7f06f7934e", + "reference": "4ae32dd9ab8860a4bbd750ad269cba7f06f7934e", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "^1.0|^2.0", + "php": "^5.4 || ^7.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "apigen/apigen": "^4.1", + "codeception/aspect-mock": "^1.0 | ^2.0", + "doctrine/annotations": "~1.2.0", + "goaop/framework": "1.0.0-alpha.2 | ^1.0 | ^2.1", + "ircmaxell/random-lib": "^1.1", + "jakub-onderka/php-parallel-lint": "^0.9.0", + "mockery/mockery": "^0.9.4", + "moontoast/math": "^1.1", + "php-mock/php-mock-phpunit": "^0.3|^1.1", + "phpunit/phpunit": "^4.7|>=5.0 <5.4", + "satooshi/php-coveralls": "^0.6.1", + "squizlabs/php_codesniffer": "^2.3" + }, + "suggest": { + "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator", + "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator", + "ircmaxell/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).", + "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marijn Huizendveld", + "email": "marijn.huizendveld@gmail.com" + }, + { + "name": "Thibaud Fabre", + "email": "thibaud@aztech.io" + }, + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", + "homepage": "https://github.com/ramsey/uuid", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "time": "2017-03-26T20:37:53+00:00" + }, + { + "name": "seld/cli-prompt", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/cli-prompt.git", + "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/a19a7376a4689d4d94cab66ab4f3c816019ba8dd", + "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\CliPrompt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Allows you to prompt for user input on the command line, and optionally hide the characters they type", + "keywords": [ + "cli", + "console", + "hidden", + "input", + "prompt" + ], + "time": "2017-03-18T11:32:45+00:00" + }, + { + "name": "seld/jsonlint", + "version": "1.7.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "d15f59a67ff805a44c50ea0516d2341740f81a38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/d15f59a67ff805a44c50ea0516d2341740f81a38", + "reference": "d15f59a67ff805a44c50ea0516d2341740f81a38", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "time": "2018-01-24T12:46:19+00:00" + }, + { + "name": "seld/phar-utils", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/7009b5139491975ef6486545a39f3e6dad5ac30a", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\PharUtils\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "PHAR file format utilities, for when PHP phars you up", + "keywords": [ + "phra" + ], + "time": "2015-10-13T18:44:15+00:00" + }, + { + "name": "symfony/console", + "version": "v2.8.36", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "a6ff8b2ffa4eb43046828b303af2e3fedadacc27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/a6ff8b2ffa4eb43046828b303af2e3fedadacc27", + "reference": "a6ff8b2ffa4eb43046828b303af2e3fedadacc27", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/debug": "^2.7.2|~3.0.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1|~3.0.0", + "symfony/process": "~2.1|~3.0.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2018-02-26T15:33:21+00:00" + }, + { + "name": "symfony/debug", + "version": "v3.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/697c527acd9ea1b2d3efac34d9806bf255278b0a", + "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + }, + "require-dev": { + "symfony/class-loader": "~2.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Debug Component", + "homepage": "https://symfony.com", + "time": "2016-07-30T07:22:48+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.8.36", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "f5d2d7dcc33b89e20c2696ea9afcbddf6540081c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f5d2d7dcc33b89e20c2696ea9afcbddf6540081c", + "reference": "f5d2d7dcc33b89e20c2696ea9afcbddf6540081c", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^2.0.5|~3.0.0", + "symfony/dependency-injection": "~2.6|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/stopwatch": "~2.3|~3.0.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2018-02-11T16:53:59+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v3.4.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "253a4490b528597aa14d2bf5aeded6f5e5e4a541" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/253a4490b528597aa14d2bf5aeded6f5e5e4a541", + "reference": "253a4490b528597aa14d2bf5aeded6f5e5e4a541", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "time": "2018-02-22T10:48:49+00:00" + }, + { + "name": "symfony/finder", + "version": "v3.4.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "a479817ce0a9e4adfd7d39c6407c95d97c254625" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/a479817ce0a9e4adfd7d39c6407c95d97c254625", + "reference": "a479817ce0a9e4adfd7d39c6407c95d97c254625", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2018-03-05T18:28:11+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b", + "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2018-01-30T19:27:44+00:00" + }, + { + "name": "symfony/process", + "version": "v2.8.36", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "756f614c5061729ea245ac6717231f7e3bfb74f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/756f614c5061729ea245ac6717231f7e3bfb74f9", + "reference": "756f614c5061729ea245ac6717231f7e3bfb74f9", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2018-02-12T17:44:58+00:00" + }, + { + "name": "tedivm/jshrink", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/tedious/JShrink.git", + "reference": "688527a2e854d7935f24f24c7d5eb1b604742bf9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tedious/JShrink/zipball/688527a2e854d7935f24f24c7d5eb1b604742bf9", + "reference": "688527a2e854d7935f24f24c7d5eb1b604742bf9", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "fabpot/php-cs-fixer": "0.4.0", + "phpunit/phpunit": "4.0.*", + "satooshi/php-coveralls": "dev-master" + }, + "type": "library", + "autoload": { + "psr-0": { + "JShrink": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Robert Hafner", + "email": "tedivm@tedivm.com" + } + ], + "description": "Javascript Minifier built in PHP", + "homepage": "http://github.com/tedious/JShrink", + "keywords": [ + "javascript", + "minifier" + ], + "time": "2015-07-04T07:35:09+00:00" + }, + { + "name": "tubalmartin/cssmin", + "version": "v4.1.0", + "source": { + "type": "git", + "url": "https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port.git", + "reference": "1c7ae93cf6b392d4dae5c4ae18979918413af16e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tubalmartin/YUI-CSS-compressor-PHP-port/zipball/1c7ae93cf6b392d4dae5c4ae18979918413af16e", + "reference": "1c7ae93cf6b392d4dae5c4ae18979918413af16e", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "php": ">=5.3.2" + }, + "require-dev": { + "cogpowered/finediff": "0.3.*", + "phpunit/phpunit": "4.8.*" + }, + "bin": [ + "cssmin" + ], + "type": "library", + "autoload": { + "psr-4": { + "tubalmartin\\CssMin\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Túbal Martín", + "homepage": "http://tubalmartin.me/" + } + ], + "description": "A PHP port of the YUI CSS compressor", + "homepage": "https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port", + "keywords": [ + "compress", + "compressor", + "css", + "cssmin", + "minify", + "yui" + ], + "time": "2017-05-16T13:45:26+00:00" + }, + { + "name": "webonyx/graphql-php", + "version": "v0.11.5", + "source": { + "type": "git", + "url": "https://github.com/webonyx/graphql-php.git", + "reference": "b97cad0f4a50131c85d9224e8e36ebbcf1c6b425" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webonyx/graphql-php/zipball/b97cad0f4a50131c85d9224e8e36ebbcf1c6b425", + "reference": "b97cad0f4a50131c85d9224e8e36ebbcf1c6b425", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.5,<8.0-DEV" + }, + "require-dev": { + "phpunit/phpunit": "^4.8", + "psr/http-message": "^1.0" + }, + "suggest": { + "psr/http-message": "To use standard GraphQL server", + "react/promise": "To leverage async resolving on React PHP platform" + }, + "type": "library", + "autoload": { + "files": [ + "src/deprecated.php" + ], + "psr-4": { + "GraphQL\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "description": "A PHP port of GraphQL reference implementation", + "homepage": "https://github.com/webonyx/graphql-php", + "keywords": [ + "api", + "graphql" + ], + "time": "2017-12-12T09:03:21+00:00" + }, + { + "name": "zendframework/zend-captcha", + "version": "2.7.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-captcha.git", + "reference": "2d56293a5ae3e45e7c8ee7030aa8b305768d8014" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-captcha/zipball/2d56293a5ae3e45e7c8ee7030aa8b305768d8014", + "reference": "2d56293a5ae3e45e7c8ee7030aa8b305768d8014", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-math": "^2.6 || ^3.0", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-session": "^2.6", + "zendframework/zend-text": "^2.6", + "zendframework/zend-validator": "^2.6", + "zendframework/zendservice-recaptcha": "^3.0" + }, + "suggest": { + "zendframework/zend-i18n-resources": "Translations of captcha messages", + "zendframework/zend-session": "Zend\\Session component", + "zendframework/zend-text": "Zend\\Text component", + "zendframework/zend-validator": "Zend\\Validator component", + "zendframework/zendservice-recaptcha": "ZendService\\ReCaptcha component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev", + "dev-develop": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Captcha\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-captcha", + "keywords": [ + "captcha", + "zf2" + ], + "time": "2017-02-23T08:09:44+00:00" + }, + { + "name": "zendframework/zend-code", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-code.git", + "reference": "2899c17f83a7207f2d7f53ec2f421204d3beea27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-code/zipball/2899c17f83a7207f2d7f53ec2f421204d3beea27", + "reference": "2899c17f83a7207f2d7f53ec2f421204d3beea27", + "shasum": "" + }, + "require": { + "php": "^5.6 || 7.0.0 - 7.0.4 || ^7.0.6", + "zendframework/zend-eventmanager": "^2.6 || ^3.0" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "ext-phar": "*", + "phpunit/phpunit": "^4.8.21", + "squizlabs/php_codesniffer": "^2.5", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "suggest": { + "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", + "zendframework/zend-stdlib": "Zend\\Stdlib component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev", + "dev-develop": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Code\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides facilities to generate arbitrary code using an object oriented interface", + "homepage": "https://github.com/zendframework/zend-code", + "keywords": [ + "code", + "zf2" + ], + "time": "2016-10-24T13:23:32+00:00" + }, + { + "name": "zendframework/zend-config", + "version": "2.6.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-config.git", + "reference": "2920e877a9f6dca9fa8f6bd3b1ffc2e19bb1e30d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-config/zipball/2920e877a9f6dca9fa8f6bd3b1ffc2e19bb1e30d", + "reference": "2920e877a9f6dca9fa8f6bd3b1ffc2e19bb1e30d", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-filter": "^2.6", + "zendframework/zend-i18n": "^2.5", + "zendframework/zend-json": "^2.6.1", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3" + }, + "suggest": { + "zendframework/zend-filter": "Zend\\Filter component", + "zendframework/zend-i18n": "Zend\\I18n component", + "zendframework/zend-json": "Zend\\Json to use the Json reader or writer classes", + "zendframework/zend-servicemanager": "Zend\\ServiceManager for use with the Config Factory to retrieve reader and writer instances" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev", + "dev-develop": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Config\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides a nested object property based user interface for accessing this configuration data within application code", + "homepage": "https://github.com/zendframework/zend-config", + "keywords": [ + "config", + "zf2" + ], + "time": "2016-02-04T23:01:10+00:00" + }, + { + "name": "zendframework/zend-console", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-console.git", + "reference": "e8aa08da83de3d265256c40ba45cd649115f0e18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-console/zipball/e8aa08da83de3d265256c40ba45cd649115f0e18", + "reference": "e8aa08da83de3d265256c40ba45cd649115f0e18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-stdlib": "^2.7.7 || ^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-filter": "^2.7.2", + "zendframework/zend-json": "^2.6 || ^3.0", + "zendframework/zend-validator": "^2.10.1" + }, + "suggest": { + "zendframework/zend-filter": "To support DefaultRouteMatcher usage", + "zendframework/zend-validator": "To support DefaultRouteMatcher usage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7.x-dev", + "dev-develop": "2.8.x-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Console\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Build console applications using getopt syntax or routing, complete with prompts", + "keywords": [ + "ZendFramework", + "console", + "zf" + ], + "time": "2018-01-25T19:08:04+00:00" + }, + { + "name": "zendframework/zend-crypt", + "version": "2.6.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-crypt.git", + "reference": "1b2f5600bf6262904167116fa67b58ab1457036d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-crypt/zipball/1b2f5600bf6262904167116fa67b58ab1457036d", + "reference": "1b2f5600bf6262904167116fa67b58ab1457036d", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "~1.0", + "php": "^5.5 || ^7.0", + "zendframework/zend-math": "^2.6", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "ext-mcrypt": "Required for most features of Zend\\Crypt" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev", + "dev-develop": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Crypt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-crypt", + "keywords": [ + "crypt", + "zf2" + ], + "time": "2016-02-03T23:46:30+00:00" + }, + { + "name": "zendframework/zend-db", + "version": "2.9.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-db.git", + "reference": "1651abb1b33fc8fbd2d78ff9e2abb526cc2cf666" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-db/zipball/1651abb1b33fc8fbd2d78ff9e2abb526cc2cf666", + "reference": "1651abb1b33fc8fbd2d78ff9e2abb526cc2cf666", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.25 || ^6.4.4", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", + "zendframework/zend-hydrator": "^1.1 || ^2.1", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3" + }, + "suggest": { + "zendframework/zend-eventmanager": "Zend\\EventManager component", + "zendframework/zend-hydrator": "Zend\\Hydrator component for using HydratingResultSets", + "zendframework/zend-servicemanager": "Zend\\ServiceManager component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.9-dev", + "dev-develop": "2.10-dev" + }, + "zf": { + "component": "Zend\\Db", + "config-provider": "Zend\\Db\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Zend\\Db\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Database abstraction layer, SQL abstraction, result set abstraction, and RowDataGateway and TableDataGateway implementations", + "keywords": [ + "ZendFramework", + "db", + "zf" + ], + "time": "2017-12-11T14:57:52+00:00" + }, + { + "name": "zendframework/zend-di", + "version": "2.6.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-di.git", + "reference": "1fd1ba85660b5a2718741b38639dc7c4c3194b37" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-di/zipball/1fd1ba85660b5a2718741b38639dc7c4c3194b37", + "reference": "1fd1ba85660b5a2718741b38639dc7c4c3194b37", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "^1.1", + "php": "^5.5 || ^7.0", + "zendframework/zend-code": "^2.6 || ^3.0", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev", + "dev-develop": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Di\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-di", + "keywords": [ + "di", + "zf2" + ], + "time": "2016-04-25T20:58:11+00:00" + }, + { + "name": "zendframework/zend-diactoros", + "version": "1.7.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-diactoros.git", + "reference": "bf26aff803a11c5cc8eb7c4878a702c403ec67f1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/bf26aff803a11c5cc8eb7c4878a702c403ec67f1", + "reference": "bf26aff803a11c5cc8eb7c4878a702c403ec67f1", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "psr/http-message": "^1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-dom": "*", + "ext-libxml": "*", + "phpunit/phpunit": "^5.7.16 || ^6.0.8", + "zendframework/zend-coding-standard": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7.x-dev", + "dev-develop": "1.8.x-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Diactoros\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "description": "PSR HTTP Message implementations", + "homepage": "https://github.com/zendframework/zend-diactoros", + "keywords": [ + "http", + "psr", + "psr-7" + ], + "time": "2018-02-26T15:44:50+00:00" + }, + { + "name": "zendframework/zend-escaper", + "version": "2.5.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-escaper.git", + "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/2dcd14b61a72d8b8e27d579c6344e12c26141d4e", + "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Escaper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-escaper", + "keywords": [ + "escaper", + "zf2" + ], + "time": "2016-06-30T19:48:38+00:00" + }, + { + "name": "zendframework/zend-eventmanager", + "version": "2.6.4", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-eventmanager.git", + "reference": "d238c443220dce4b6396579c8ab2200ec25f9108" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/d238c443220dce4b6396579c8ab2200ec25f9108", + "reference": "d238c443220dce4b6396579c8ab2200ec25f9108", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "zendframework/zend-stdlib": "^2.7" + }, + "require-dev": { + "athletic/athletic": "dev-master", + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-release-2.6": "2.6-dev", + "dev-master": "3.0-dev", + "dev-develop": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\EventManager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-eventmanager", + "keywords": [ + "eventmanager", + "zf2" + ], + "time": "2017-12-12T17:48:56+00:00" + }, + { + "name": "zendframework/zend-filter", + "version": "2.7.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-filter.git", + "reference": "b8d0ff872f126631bf63a932e33aa2d22d467175" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-filter/zipball/b8d0ff872f126631bf63a932e33aa2d22d467175", + "reference": "b8d0ff872f126631bf63a932e33aa2d22d467175", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "pear/archive_tar": "^1.4", + "phpunit/phpunit": "^6.0.10 || ^5.7.17", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-crypt": "^2.6 || ^3.0", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-uri": "^2.5" + }, + "suggest": { + "zendframework/zend-crypt": "Zend\\Crypt component, for encryption filters", + "zendframework/zend-i18n": "Zend\\I18n component for filters depending on i18n functionality", + "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for using the filter chain functionality", + "zendframework/zend-uri": "Zend\\Uri component, for the UriNormalize filter" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev", + "dev-develop": "2.8-dev" + }, + "zf": { + "component": "Zend\\Filter", + "config-provider": "Zend\\Filter\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Zend\\Filter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides a set of commonly needed data filters", + "homepage": "https://github.com/zendframework/zend-filter", + "keywords": [ + "filter", + "zf2" + ], + "time": "2017-05-17T20:56:17+00:00" + }, + { + "name": "zendframework/zend-form", + "version": "2.11.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-form.git", + "reference": "b68a9f07d93381613b68817091d0505ca94d3363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-form/zipball/b68a9f07d93381613b68817091d0505ca94d3363", + "reference": "b68a9f07d93381613b68817091d0505ca94d3363", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-hydrator": "^1.1 || ^2.1", + "zendframework/zend-inputfilter": "^2.8", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "phpunit/phpunit": "^5.7.23 || ^6.5.3", + "zendframework/zend-cache": "^2.6.1", + "zendframework/zend-captcha": "^2.7.1", + "zendframework/zend-code": "^2.6 || ^3.0", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-escaper": "^2.5", + "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", + "zendframework/zend-filter": "^2.6", + "zendframework/zend-i18n": "^2.6", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-session": "^2.8.1", + "zendframework/zend-text": "^2.6", + "zendframework/zend-validator": "^2.6", + "zendframework/zend-view": "^2.6.2", + "zendframework/zendservice-recaptcha": "^3.0.0" + }, + "suggest": { + "zendframework/zend-captcha": "^2.7.1, required for using CAPTCHA form elements", + "zendframework/zend-code": "^2.6 || ^3.0, required to use zend-form annotations support", + "zendframework/zend-eventmanager": "^2.6.2 || ^3.0, reuired for zend-form annotations support", + "zendframework/zend-i18n": "^2.6, required when using zend-form view helpers", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3, required to use the form factories or provide services", + "zendframework/zend-view": "^2.6.2, required for using the zend-form view helpers", + "zendframework/zendservice-recaptcha": "in order to use the ReCaptcha form element" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.11.x-dev", + "dev-develop": "2.12.x-dev" + }, + "zf": { + "component": "Zend\\Form", + "config-provider": "Zend\\Form\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Zend\\Form\\": "src/" + }, + "files": [ + "autoload/formElementManagerPolyfill.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Validate and display simple and complex forms, casting forms to business objects and vice versa", + "keywords": [ + "ZendFramework", + "form", + "zf" + ], + "time": "2017-12-06T21:09:08+00:00" + }, + { + "name": "zendframework/zend-http", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-http.git", + "reference": "78aa510c0ea64bfb2aa234f50c4f232c9531acfa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-http/zipball/78aa510c0ea64bfb2aa234f50c4f232c9531acfa", + "reference": "78aa510c0ea64bfb2aa234f50c4f232c9531acfa", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-loader": "^2.5.1", + "zendframework/zend-stdlib": "^3.1 || ^2.7.7", + "zendframework/zend-uri": "^2.5.2", + "zendframework/zend-validator": "^2.10.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.4.1 || ^5.7.15", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-config": "^3.1 || ^2.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev", + "dev-develop": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Http\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides an easy interface for performing Hyper-Text Transfer Protocol (HTTP) requests", + "homepage": "https://github.com/zendframework/zend-http", + "keywords": [ + "ZendFramework", + "http", + "http client", + "zend", + "zf" + ], + "time": "2017-10-13T12:06:24+00:00" + }, + { + "name": "zendframework/zend-hydrator", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-hydrator.git", + "reference": "22652e1661a5a10b3f564cf7824a2206cf5a4a65" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-hydrator/zipball/22652e1661a5a10b3f564cf7824a2206cf5a4a65", + "reference": "22652e1661a5a10b3f564cf7824a2206cf5a4a65", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "^2.0@dev", + "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", + "zendframework/zend-filter": "^2.6", + "zendframework/zend-inputfilter": "^2.6", + "zendframework/zend-serializer": "^2.6.1", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3" + }, + "suggest": { + "zendframework/zend-eventmanager": "^2.6.2 || ^3.0, to support aggregate hydrator usage", + "zendframework/zend-filter": "^2.6, to support naming strategy hydrator usage", + "zendframework/zend-serializer": "^2.6.1, to use the SerializableStrategy", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3, to support hydrator plugin manager usage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-release-1.0": "1.0-dev", + "dev-release-1.1": "1.1-dev", + "dev-master": "2.0-dev", + "dev-develop": "2.1-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Hydrator\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-hydrator", + "keywords": [ + "hydrator", + "zf2" + ], + "time": "2016-02-18T22:38:26+00:00" + }, + { + "name": "zendframework/zend-i18n", + "version": "2.7.4", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-i18n.git", + "reference": "d3431e29cc00c2a1c6704e601d4371dbf24f6a31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-i18n/zipball/d3431e29cc00c2a1c6704e601d4371dbf24f6a31", + "reference": "d3431e29cc00c2a1c6704e601d4371dbf24f6a31", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^5.6", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0.8 || ^5.7.15", + "zendframework/zend-cache": "^2.6.1", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-config": "^2.6", + "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", + "zendframework/zend-filter": "^2.6.1", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-validator": "^2.6", + "zendframework/zend-view": "^2.6.3" + }, + "suggest": { + "ext-intl": "Required for most features of Zend\\I18n; included in default builds of PHP", + "zendframework/zend-cache": "Zend\\Cache component", + "zendframework/zend-config": "Zend\\Config component", + "zendframework/zend-eventmanager": "You should install this package to use the events in the translator", + "zendframework/zend-filter": "You should install this package to use the provided filters", + "zendframework/zend-i18n-resources": "Translation resources", + "zendframework/zend-servicemanager": "Zend\\ServiceManager component", + "zendframework/zend-validator": "You should install this package to use the provided validators", + "zendframework/zend-view": "You should install this package to use the provided view helpers" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev", + "dev-develop": "2.8-dev" + }, + "zf": { + "component": "Zend\\I18n", + "config-provider": "Zend\\I18n\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Zend\\I18n\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-i18n", + "keywords": [ + "i18n", + "zf2" + ], + "time": "2017-05-17T17:00:12+00:00" + }, + { + "name": "zendframework/zend-inputfilter", + "version": "2.8.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-inputfilter.git", + "reference": "55d1430db559e9781b147e73c2c0ce6635d8efe2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-inputfilter/zipball/55d1430db559e9781b147e73c2c0ce6635d8efe2", + "reference": "55d1430db559e9781b147e73c2c0ce6635d8efe2", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-filter": "^2.6", + "zendframework/zend-servicemanager": "^2.7.10 || ^3.3.1", + "zendframework/zend-stdlib": "^2.7 || ^3.0", + "zendframework/zend-validator": "^2.10.1" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "zendframework/zend-coding-standard": "~1.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8.x-dev", + "dev-develop": "2.9.x-dev" + }, + "zf": { + "component": "Zend\\InputFilter", + "config-provider": "Zend\\InputFilter\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Zend\\InputFilter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Normalize and validate input sets from the web, APIs, the CLI, and more, including files", + "keywords": [ + "ZendFramework", + "inputfilter", + "zf" + ], + "time": "2018-01-22T19:41:18+00:00" + }, + { + "name": "zendframework/zend-json", + "version": "2.6.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-json.git", + "reference": "4c8705dbe4ad7d7e51b2876c5b9eea0ef916ba28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-json/zipball/4c8705dbe4ad7d7e51b2876c5b9eea0ef916ba28", + "reference": "4c8705dbe4ad7d7e51b2876c5b9eea0ef916ba28", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-http": "^2.5.4", + "zendframework/zend-server": "^2.6.1", + "zendframework/zend-stdlib": "^2.5 || ^3.0", + "zendframework/zendxml": "^1.0.2" + }, + "suggest": { + "zendframework/zend-http": "Zend\\Http component, required to use Zend\\Json\\Server", + "zendframework/zend-server": "Zend\\Server component, required to use Zend\\Json\\Server", + "zendframework/zend-stdlib": "Zend\\Stdlib component, for use with caching Zend\\Json\\Server responses", + "zendframework/zendxml": "To support Zend\\Json\\Json::fromXml() usage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev", + "dev-develop": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Json\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides convenience methods for serializing native PHP to JSON and decoding JSON to native PHP", + "homepage": "https://github.com/zendframework/zend-json", + "keywords": [ + "json", + "zf2" + ], + "time": "2016-02-04T21:20:26+00:00" + }, + { + "name": "zendframework/zend-loader", + "version": "2.5.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-loader.git", + "reference": "c5fd2f071bde071f4363def7dea8dec7393e135c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/c5fd2f071bde071f4363def7dea8dec7393e135c", + "reference": "c5fd2f071bde071f4363def7dea8dec7393e135c", + "shasum": "" + }, + "require": { + "php": ">=5.3.23" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Loader\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-loader", + "keywords": [ + "loader", + "zf2" + ], + "time": "2015-06-03T14:05:47+00:00" + }, + { + "name": "zendframework/zend-log", + "version": "2.9.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-log.git", + "reference": "bf7489578d092d6ff7508117d1d920a4764fbd6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-log/zipball/bf7489578d092d6ff7508117d1d920a4764fbd6a", + "reference": "bf7489578d092d6ff7508117d1d920a4764fbd6a", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "psr/log": "^1.0", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "mikey179/vfsstream": "^1.6", + "phpunit/phpunit": "^5.7.15 || ^6.0.8", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-db": "^2.6", + "zendframework/zend-escaper": "^2.5", + "zendframework/zend-filter": "^2.5", + "zendframework/zend-mail": "^2.6.1", + "zendframework/zend-validator": "^2.6" + }, + "suggest": { + "ext-mongo": "mongo extension to use Mongo writer", + "ext-mongodb": "mongodb extension to use MongoDB writer", + "zendframework/zend-console": "Zend\\Console component to use the RequestID log processor", + "zendframework/zend-db": "Zend\\Db component to use the database log writer", + "zendframework/zend-escaper": "Zend\\Escaper component, for use in the XML log formatter", + "zendframework/zend-mail": "Zend\\Mail component to use the email log writer", + "zendframework/zend-validator": "Zend\\Validator component to block invalid log messages" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.9-dev", + "dev-develop": "2.10-dev" + }, + "zf": { + "component": "Zend\\Log", + "config-provider": "Zend\\Log\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Zend\\Log\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "component for general purpose logging", + "homepage": "https://github.com/zendframework/zend-log", + "keywords": [ + "log", + "logging", + "zf2" + ], + "time": "2017-05-17T16:03:26+00:00" + }, + { + "name": "zendframework/zend-mail", + "version": "2.8.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-mail.git", + "reference": "248230940ab1453b2a532a8fde76c5a6470d7aad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-mail/zipball/248230940ab1453b2a532a8fde76c5a6470d7aad", + "reference": "248230940ab1453b2a532a8fde76c5a6470d7aad", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": "^7.0 || ^5.6", + "zendframework/zend-loader": "^2.5", + "zendframework/zend-mime": "^2.5", + "zendframework/zend-stdlib": "^2.7 || ^3.0", + "zendframework/zend-validator": "^2.6" + }, + "require-dev": { + "phpunit/phpunit": "^6.0.8 || ^5.7.15", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-config": "^2.6", + "zendframework/zend-crypt": "^2.6", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3" + }, + "suggest": { + "ext-intl": "Handle IDN in AddressList hostnames", + "zendframework/zend-crypt": "Crammd5 support in SMTP Auth", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3 when using SMTP to deliver messages" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev", + "dev-develop": "2.9-dev" + }, + "zf": { + "component": "Zend\\Mail", + "config-provider": "Zend\\Mail\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Zend\\Mail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides generalized functionality to compose and send both text and MIME-compliant multipart e-mail messages", + "homepage": "https://github.com/zendframework/zend-mail", + "keywords": [ + "mail", + "zf2" + ], + "time": "2017-06-08T20:03:58+00:00" + }, + { + "name": "zendframework/zend-math", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-math.git", + "reference": "f4358090d5d23973121f1ed0b376184b66d9edec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-math/zipball/f4358090d5d23973121f1ed0b376184b66d9edec", + "reference": "f4358090d5d23973121f1ed0b376184b66d9edec", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "ircmaxell/random-lib": "~1.1", + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "ext-bcmath": "If using the bcmath functionality", + "ext-gmp": "If using the gmp functionality", + "ircmaxell/random-lib": "Fallback random byte generator for Zend\\Math\\Rand if Mcrypt extensions is unavailable" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev", + "dev-develop": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-math", + "keywords": [ + "math", + "zf2" + ], + "time": "2016-04-07T16:29:53+00:00" + }, + { + "name": "zendframework/zend-mime", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-mime.git", + "reference": "5db38e92f8a6c7c5e25c8afce6e2d0bd49340c5f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-mime/zipball/5db38e92f8a6c7c5e25c8afce6e2d0bd49340c5f", + "reference": "5db38e92f8a6c7c5e25c8afce6e2d0bd49340c5f", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.21 || ^6.3", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-mail": "^2.6" + }, + "suggest": { + "zendframework/zend-mail": "Zend\\Mail component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev", + "dev-develop": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Mime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Create and parse MIME messages and parts", + "homepage": "https://github.com/zendframework/zend-mime", + "keywords": [ + "ZendFramework", + "mime", + "zf" + ], + "time": "2017-11-28T15:02:22+00:00" + }, + { + "name": "zendframework/zend-modulemanager", + "version": "2.8.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-modulemanager.git", + "reference": "394df6e12248ac430a312d4693f793ee7120baa6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-modulemanager/zipball/394df6e12248ac430a312d4693f793ee7120baa6", + "reference": "394df6e12248ac430a312d4693f793ee7120baa6", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-config": "^3.1 || ^2.6", + "zendframework/zend-eventmanager": "^3.2 || ^2.6.3", + "zendframework/zend-stdlib": "^3.1 || ^2.7" + }, + "require-dev": { + "phpunit/phpunit": "^6.0.8 || ^5.7.15", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-console": "^2.6", + "zendframework/zend-di": "^2.6", + "zendframework/zend-loader": "^2.5", + "zendframework/zend-mvc": "^3.0 || ^2.7", + "zendframework/zend-servicemanager": "^3.0.3 || ^2.7.5" + }, + "suggest": { + "zendframework/zend-console": "Zend\\Console component", + "zendframework/zend-loader": "Zend\\Loader component if you are not using Composer autoloading for your modules", + "zendframework/zend-mvc": "Zend\\Mvc component", + "zendframework/zend-servicemanager": "Zend\\ServiceManager component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev", + "dev-develop": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\ModuleManager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Modular application system for zend-mvc applications", + "homepage": "https://github.com/zendframework/zend-modulemanager", + "keywords": [ + "ZendFramework", + "modulemanager", + "zf" + ], + "time": "2017-12-02T06:11:18+00:00" + }, + { + "name": "zendframework/zend-mvc", + "version": "2.7.13", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-mvc.git", + "reference": "9dcaaad145254d023d3cd3559bf29e430f2884b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-mvc/zipball/9dcaaad145254d023d3cd3559bf29e430f2884b2", + "reference": "9dcaaad145254d023d3cd3559bf29e430f2884b2", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "^1.1", + "php": "^5.5 || ^7.0", + "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", + "zendframework/zend-form": "^2.8.2", + "zendframework/zend-hydrator": "^1.1 || ^2.1", + "zendframework/zend-psr7bridge": "^0.2", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-stdlib": "^2.7.5 || ^3.0" + }, + "replace": { + "zendframework/zend-router": "^2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "^4.5", + "sebastian/version": "^1.0.4", + "zendframework/zend-authentication": "^2.5.3", + "zendframework/zend-cache": "^2.6.1", + "zendframework/zend-console": "^2.6", + "zendframework/zend-di": "^2.6", + "zendframework/zend-filter": "^2.6.1", + "zendframework/zend-http": "^2.5.4", + "zendframework/zend-i18n": "^2.6", + "zendframework/zend-inputfilter": "^2.6", + "zendframework/zend-json": "^2.6.1", + "zendframework/zend-log": "^2.7.1", + "zendframework/zend-modulemanager": "^2.7.1", + "zendframework/zend-serializer": "^2.6.1", + "zendframework/zend-session": "^2.6.2", + "zendframework/zend-text": "^2.6", + "zendframework/zend-uri": "^2.5", + "zendframework/zend-validator": "^2.6", + "zendframework/zend-view": "^2.6.3" + }, + "suggest": { + "zendframework/zend-authentication": "Zend\\Authentication component for Identity plugin", + "zendframework/zend-config": "Zend\\Config component", + "zendframework/zend-console": "Zend\\Console component", + "zendframework/zend-di": "Zend\\Di component", + "zendframework/zend-filter": "Zend\\Filter component", + "zendframework/zend-http": "Zend\\Http component", + "zendframework/zend-i18n": "Zend\\I18n component for translatable segments", + "zendframework/zend-inputfilter": "Zend\\Inputfilter component", + "zendframework/zend-json": "Zend\\Json component", + "zendframework/zend-log": "Zend\\Log component", + "zendframework/zend-modulemanager": "Zend\\ModuleManager component", + "zendframework/zend-serializer": "Zend\\Serializer component", + "zendframework/zend-servicemanager-di": "^1.0.1, if using zend-servicemanager v3 and requiring the zend-di integration", + "zendframework/zend-session": "Zend\\Session component for FlashMessenger, PRG, and FPRG plugins", + "zendframework/zend-text": "Zend\\Text component", + "zendframework/zend-uri": "Zend\\Uri component", + "zendframework/zend-validator": "Zend\\Validator component", + "zendframework/zend-view": "Zend\\View component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev", + "dev-develop": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Mvc\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-mvc", + "keywords": [ + "mvc", + "zf2" + ], + "time": "2017-12-14T22:44:10+00:00" + }, + { + "name": "zendframework/zend-psr7bridge", + "version": "0.2.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-psr7bridge.git", + "reference": "86c0b53b0c6381391c4add4a93a56e51d5c74605" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-psr7bridge/zipball/86c0b53b0c6381391c4add4a93a56e51d5c74605", + "reference": "86c0b53b0c6381391c4add4a93a56e51d5c74605", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "psr/http-message": "^1.0", + "zendframework/zend-diactoros": "^1.1", + "zendframework/zend-http": "^2.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.7", + "squizlabs/php_codesniffer": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev", + "dev-develop": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Psr7Bridge\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "PSR-7 <-> Zend\\Http bridge", + "homepage": "https://github.com/zendframework/zend-psr7bridge", + "keywords": [ + "http", + "psr", + "psr-7" + ], + "time": "2016-05-10T21:44:39+00:00" + }, + { + "name": "zendframework/zend-serializer", + "version": "2.8.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-serializer.git", + "reference": "7ac42b9a47e9cb23895173a3096bc3b3fb7ac580" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-serializer/zipball/7ac42b9a47e9cb23895173a3096bc3b3fb7ac580", + "reference": "7ac42b9a47e9cb23895173a3096bc3b3fb7ac580", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-json": "^2.5 || ^3.0", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "doctrine/instantiator": "1.0.*", + "phpunit/phpunit": "^5.5", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-math": "^2.6", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3" + }, + "suggest": { + "zendframework/zend-math": "(^2.6 || ^3.0) To support Python Pickle serialization", + "zendframework/zend-servicemanager": "(^2.7.5 || ^3.0.3) To support plugin manager support" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev", + "dev-develop": "2.9-dev" + }, + "zf": { + "component": "Zend\\Serializer", + "config-provider": "Zend\\Serializer\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Zend\\Serializer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides an adapter based interface to simply generate storable representation of PHP types by different facilities, and recover", + "homepage": "https://github.com/zendframework/zend-serializer", + "keywords": [ + "serializer", + "zf2" + ], + "time": "2017-11-20T22:21:04+00:00" + }, + { + "name": "zendframework/zend-server", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-server.git", + "reference": "7cb617ca3e9b24579f544a244ee79ae61f480914" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-server/zipball/7cb617ca3e9b24579f544a244ee79ae61f480914", + "reference": "7cb617ca3e9b24579f544a244ee79ae61f480914", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-code": "^2.5 || ^3.0", + "zendframework/zend-stdlib": "^2.5 || ^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8", + "squizlabs/php_codesniffer": "^2.3.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev", + "dev-develop": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-server", + "keywords": [ + "server", + "zf2" + ], + "time": "2016-06-20T22:27:55+00:00" + }, + { + "name": "zendframework/zend-servicemanager", + "version": "2.7.10", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-servicemanager.git", + "reference": "ba7069c94c9af93122be9fa31cddd37f7707d5b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-servicemanager/zipball/ba7069c94c9af93122be9fa31cddd37f7707d5b4", + "reference": "ba7069c94c9af93122be9fa31cddd37f7707d5b4", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "~1.0", + "php": "^5.5 || ^7.0" + }, + "require-dev": { + "athletic/athletic": "dev-master", + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-di": "~2.5", + "zendframework/zend-mvc": "~2.5" + }, + "suggest": { + "ocramius/proxy-manager": "ProxyManager 0.5.* to handle lazy initialization of services", + "zendframework/zend-di": "Zend\\Di component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev", + "dev-develop": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\ServiceManager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-servicemanager", + "keywords": [ + "servicemanager", + "zf2" + ], + "time": "2017-12-05T16:27:36+00:00" + }, + { + "name": "zendframework/zend-session", + "version": "2.8.5", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-session.git", + "reference": "2cfd90e1a2f6b066b9f908599251d8f64f07021b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-session/zipball/2cfd90e1a2f6b066b9f908599251d8f64f07021b", + "reference": "2cfd90e1a2f6b066b9f908599251d8f64f07021b", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "container-interop/container-interop": "^1.1", + "mongodb/mongodb": "^1.0.1", + "php-mock/php-mock-phpunit": "^1.1.2 || ^2.0", + "phpunit/phpunit": "^5.7.5 || >=6.0.13 <6.5.0", + "zendframework/zend-cache": "^2.6.1", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-db": "^2.7", + "zendframework/zend-http": "^2.5.4", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-validator": "^2.6" + }, + "suggest": { + "mongodb/mongodb": "If you want to use the MongoDB session save handler", + "zendframework/zend-cache": "Zend\\Cache component", + "zendframework/zend-db": "Zend\\Db component", + "zendframework/zend-http": "Zend\\Http component", + "zendframework/zend-servicemanager": "Zend\\ServiceManager component", + "zendframework/zend-validator": "Zend\\Validator component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev", + "dev-develop": "2.9-dev" + }, + "zf": { + "component": "Zend\\Session", + "config-provider": "Zend\\Session\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Zend\\Session\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "manage and preserve session data, a logical complement of cookie data, across multiple page requests by the same client", + "keywords": [ + "ZendFramework", + "session", + "zf" + ], + "time": "2018-02-22T16:33:54+00:00" + }, + { + "name": "zendframework/zend-soap", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-soap.git", + "reference": "af03c32f0db2b899b3df8cfe29aeb2b49857d284" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-soap/zipball/af03c32f0db2b899b3df8cfe29aeb2b49857d284", + "reference": "af03c32f0db2b899b3df8cfe29aeb2b49857d284", + "shasum": "" + }, + "require": { + "ext-soap": "*", + "php": "^5.6 || ^7.0", + "zendframework/zend-server": "^2.6.1", + "zendframework/zend-stdlib": "^2.7 || ^3.0", + "zendframework/zend-uri": "^2.5.2" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.21 || ^6.3", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-config": "^2.6", + "zendframework/zend-http": "^2.5.4" + }, + "suggest": { + "zendframework/zend-http": "Zend\\Http component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7.x-dev", + "dev-develop": "2.8.x-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Soap\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-soap", + "keywords": [ + "soap", + "zf2" + ], + "time": "2018-01-29T17:51:26+00:00" + }, + { + "name": "zendframework/zend-stdlib", + "version": "2.7.7", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-stdlib.git", + "reference": "0e44eb46788f65e09e077eb7f44d2659143bcc1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/0e44eb46788f65e09e077eb7f44d2659143bcc1f", + "reference": "0e44eb46788f65e09e077eb7f44d2659143bcc1f", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "zendframework/zend-hydrator": "~1.1" + }, + "require-dev": { + "athletic/athletic": "~0.1", + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-config": "~2.5", + "zendframework/zend-eventmanager": "~2.5", + "zendframework/zend-filter": "~2.5", + "zendframework/zend-inputfilter": "~2.5", + "zendframework/zend-serializer": "~2.5", + "zendframework/zend-servicemanager": "~2.5" + }, + "suggest": { + "zendframework/zend-eventmanager": "To support aggregate hydrator usage", + "zendframework/zend-filter": "To support naming strategy hydrator usage", + "zendframework/zend-serializer": "Zend\\Serializer component", + "zendframework/zend-servicemanager": "To support hydrator plugin manager usage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-release-2.7": "2.7-dev", + "dev-master": "3.0-dev", + "dev-develop": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Stdlib\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-stdlib", + "keywords": [ + "stdlib", + "zf2" + ], + "time": "2016-04-12T21:17:31+00:00" + }, + { + "name": "zendframework/zend-text", + "version": "2.6.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-text.git", + "reference": "07ad9388e4d4f12620ad37b52a5b0e4ee7845f92" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-text/zipball/07ad9388e4d4f12620ad37b52a5b0e4ee7845f92", + "reference": "07ad9388e4d4f12620ad37b52a5b0e4ee7845f92", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-config": "^2.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev", + "dev-develop": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Text\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-text", + "keywords": [ + "text", + "zf2" + ], + "time": "2016-02-08T19:03:52+00:00" + }, + { + "name": "zendframework/zend-uri", + "version": "2.5.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-uri.git", + "reference": "0bf717a239432b1a1675ae314f7c4acd742749ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-uri/zipball/0bf717a239432b1a1675ae314f7c4acd742749ed", + "reference": "0bf717a239432b1a1675ae314f7c4acd742749ed", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "zendframework/zend-escaper": "^2.5", + "zendframework/zend-validator": "^2.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Uri\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "a component that aids in manipulating and validating » Uniform Resource Identifiers (URIs)", + "homepage": "https://github.com/zendframework/zend-uri", + "keywords": [ + "uri", + "zf2" + ], + "time": "2016-02-17T22:38:51+00:00" + }, + { + "name": "zendframework/zend-validator", + "version": "2.10.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-validator.git", + "reference": "38109ed7d8e46cfa71bccbe7e6ca80cdd035f8c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-validator/zipball/38109ed7d8e46cfa71bccbe7e6ca80cdd035f8c9", + "reference": "38109ed7d8e46cfa71bccbe7e6ca80cdd035f8c9", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "^1.1", + "php": "^5.6 || ^7.0", + "zendframework/zend-stdlib": "^2.7.6 || ^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.0.8 || ^5.7.15", + "zendframework/zend-cache": "^2.6.1", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-config": "^2.6", + "zendframework/zend-db": "^2.7", + "zendframework/zend-filter": "^2.6", + "zendframework/zend-http": "^2.5.4", + "zendframework/zend-i18n": "^2.6", + "zendframework/zend-math": "^2.6", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-session": "^2.8", + "zendframework/zend-uri": "^2.5" + }, + "suggest": { + "zendframework/zend-db": "Zend\\Db component, required by the (No)RecordExists validator", + "zendframework/zend-filter": "Zend\\Filter component, required by the Digits validator", + "zendframework/zend-i18n": "Zend\\I18n component to allow translation of validation error messages", + "zendframework/zend-i18n-resources": "Translations of validator messages", + "zendframework/zend-math": "Zend\\Math component, required by the Csrf validator", + "zendframework/zend-servicemanager": "Zend\\ServiceManager component to allow using the ValidatorPluginManager and validator chains", + "zendframework/zend-session": "Zend\\Session component, ^2.8; required by the Csrf validator", + "zendframework/zend-uri": "Zend\\Uri component, required by the Uri and Sitemap\\Loc validators" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.10.x-dev", + "dev-develop": "2.11.x-dev" + }, + "zf": { + "component": "Zend\\Validator", + "config-provider": "Zend\\Validator\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Zend\\Validator\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides a set of commonly needed validators", + "homepage": "https://github.com/zendframework/zend-validator", + "keywords": [ + "validator", + "zf2" + ], + "time": "2018-02-01T17:05:33+00:00" + }, + { + "name": "zendframework/zend-view", + "version": "2.10.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-view.git", + "reference": "4478cc5dd960e2339d88b363ef99fa278700e80e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-view/zipball/4478cc5dd960e2339d88b363ef99fa278700e80e", + "reference": "4478cc5dd960e2339d88b363ef99fa278700e80e", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", + "zendframework/zend-loader": "^2.5", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.15 || ^6.0.8", + "zendframework/zend-authentication": "^2.5", + "zendframework/zend-cache": "^2.6.1", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-config": "^2.6", + "zendframework/zend-console": "^2.6", + "zendframework/zend-escaper": "^2.5", + "zendframework/zend-feed": "^2.7", + "zendframework/zend-filter": "^2.6.1", + "zendframework/zend-http": "^2.5.4", + "zendframework/zend-i18n": "^2.6", + "zendframework/zend-json": "^2.6.1", + "zendframework/zend-log": "^2.7", + "zendframework/zend-modulemanager": "^2.7.1", + "zendframework/zend-mvc": "^2.7 || ^3.0", + "zendframework/zend-navigation": "^2.5", + "zendframework/zend-paginator": "^2.5", + "zendframework/zend-permissions-acl": "^2.6", + "zendframework/zend-router": "^3.0.1", + "zendframework/zend-serializer": "^2.6.1", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-session": "^2.8.1", + "zendframework/zend-uri": "^2.5" + }, + "suggest": { + "zendframework/zend-authentication": "Zend\\Authentication component", + "zendframework/zend-escaper": "Zend\\Escaper component", + "zendframework/zend-feed": "Zend\\Feed component", + "zendframework/zend-filter": "Zend\\Filter component", + "zendframework/zend-http": "Zend\\Http component", + "zendframework/zend-i18n": "Zend\\I18n component", + "zendframework/zend-json": "Zend\\Json component", + "zendframework/zend-mvc": "Zend\\Mvc component", + "zendframework/zend-navigation": "Zend\\Navigation component", + "zendframework/zend-paginator": "Zend\\Paginator component", + "zendframework/zend-permissions-acl": "Zend\\Permissions\\Acl component", + "zendframework/zend-servicemanager": "Zend\\ServiceManager component", + "zendframework/zend-uri": "Zend\\Uri component" + }, + "bin": [ + "bin/templatemap_generator.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.10.x-dev", + "dev-develop": "2.11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\View\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides a system of helpers, output filters, and variable escaping", + "homepage": "https://github.com/zendframework/zend-view", + "keywords": [ + "view", + "zf2" + ], + "time": "2018-01-17T22:21:50+00:00" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14T21:17:01+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v2.1.3", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", + "reference": "d30ca69f8bed931b5c630407f0a98306e33c2c39" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/d30ca69f8bed931b5c630407f0a98306e33c2c39", + "reference": "d30ca69f8bed931b5c630407f0a98306e33c2c39", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^5.3.6 || >=7.0 <7.2", + "sebastian/diff": "^1.1", + "symfony/console": "^2.3 || ^3.0", + "symfony/event-dispatcher": "^2.1 || ^3.0", + "symfony/filesystem": "^2.4 || ^3.0", + "symfony/finder": "^2.2 || ^3.0", + "symfony/polyfill-php54": "^1.0", + "symfony/polyfill-php55": "^1.3", + "symfony/polyfill-php70": "^1.0", + "symfony/polyfill-xml": "^1.3", + "symfony/process": "^2.3 || ^3.0", + "symfony/stopwatch": "^2.5 || ^3.0" + }, + "conflict": { + "hhvm": "<3.9" + }, + "require-dev": { + "gecko-packages/gecko-php-unit": "^2.0", + "justinrainbow/json-schema": "^5.0", + "phpunit/phpunit": "^4.5 || ^5.0", + "satooshi/php-coveralls": "^1.0", + "symfony/phpunit-bridge": "^3.2" + }, + "suggest": { + "ext-mbstring": "For handling non-UTF8 characters in cache singature.", + "ext-xml": "For better performance.", + "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "time": "2017-03-31T12:59:38+00:00" + }, + { + "name": "ircmaxell/password-compat", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/ircmaxell/password_compat.git", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "autoload": { + "files": [ + "lib/password.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthony Ferrara", + "email": "ircmaxell@php.net", + "homepage": "http://blog.ircmaxell.com" + } + ], + "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", + "homepage": "https://github.com/ircmaxell/password_compat", + "keywords": [ + "hashing", + "password" + ], + "time": "2014-11-20T16:49:30+00:00" + }, + { + "name": "lusitanian/oauth", + "version": "v0.8.10", + "source": { + "type": "git", + "url": "https://github.com/Lusitanian/PHPoAuthLib.git", + "reference": "09f4af38f17db6938253f4d1b171d537913ac1ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Lusitanian/PHPoAuthLib/zipball/09f4af38f17db6938253f4d1b171d537913ac1ed", + "reference": "09f4af38f17db6938253f4d1b171d537913ac1ed", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*", + "predis/predis": "0.8.*@dev", + "squizlabs/php_codesniffer": "2.*", + "symfony/http-foundation": "~2.1" + }, + "suggest": { + "ext-openssl": "Allows for usage of secure connections with the stream-based HTTP client.", + "predis/predis": "Allows using the Redis storage backend.", + "symfony/http-foundation": "Allows using the Symfony Session storage backend." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.1-dev" + } + }, + "autoload": { + "psr-0": { + "OAuth": "src", + "OAuth\\Unit": "tests" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "David Desberg", + "email": "david@daviddesberg.com" + }, + { + "name": "Elliot Chance", + "email": "elliotchance@gmail.com" + }, + { + "name": "Pieter Hordijk", + "email": "info@pieterhordijk.com" + } + ], + "description": "PHP 5.3+ oAuth 1/2 Library", + "keywords": [ + "Authentication", + "authorization", + "oauth", + "security" + ], + "time": "2016-07-12T22:15:40+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2017-10-19T19:58:43+00:00" + }, + { + "name": "pdepend/pdepend", + "version": "2.5.0", + "source": { + "type": "git", + "url": "https://github.com/pdepend/pdepend.git", + "reference": "0c50874333149c0dad5a2877801aed148f2767ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/0c50874333149c0dad5a2877801aed148f2767ff", + "reference": "0c50874333149c0dad5a2877801aed148f2767ff", + "shasum": "" + }, + "require": { + "php": ">=5.3.7", + "symfony/config": "^2.3.0|^3", + "symfony/dependency-injection": "^2.3.0|^3", + "symfony/filesystem": "^2.3.0|^3" + }, + "require-dev": { + "phpunit/phpunit": "^4.4.0,<4.8", + "squizlabs/php_codesniffer": "^2.0.0" + }, + "bin": [ + "src/bin/pdepend" + ], + "type": "library", + "autoload": { + "psr-4": { + "PDepend\\": "src/main/php/PDepend" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Official version of pdepend to be handled with Composer", + "time": "2017-01-19T14:23:36+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2017-03-05T18:14:27+00:00" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2017-03-05T17:38:23+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2017-11-30T07:14:17+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpmd/phpmd", + "version": "2.6.0", + "source": { + "type": "git", + "url": "https://github.com/phpmd/phpmd.git", + "reference": "4e9924b2c157a3eb64395460fcf56b31badc8374" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/4e9924b2c157a3eb64395460fcf56b31badc8374", + "reference": "4e9924b2c157a3eb64395460fcf56b31badc8374", + "shasum": "" + }, + "require": { + "ext-xml": "*", + "pdepend/pdepend": "^2.5", + "php": ">=5.3.9" + }, + "require-dev": { + "phpunit/phpunit": "^4.0", + "squizlabs/php_codesniffer": "^2.0" + }, + "bin": [ + "src/bin/phpmd" + ], + "type": "project", + "autoload": { + "psr-0": { + "PHPMD\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Manuel Pichler", + "email": "github@manuel-pichler.de", + "homepage": "https://github.com/manuelpichler", + "role": "Project Founder" + }, + { + "name": "Other contributors", + "homepage": "https://github.com/phpmd/phpmd/graphs/contributors", + "role": "Contributors" + }, + { + "name": "Marc Würth", + "email": "ravage@bluewin.ch", + "homepage": "https://github.com/ravage84", + "role": "Project Maintainer" + } + ], + "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", + "homepage": "http://phpmd.org/", + "keywords": [ + "mess detection", + "mess detector", + "pdepend", + "phpmd", + "pmd" + ], + "time": "2017-01-20T14:41:10+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.7.5", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/dfd6be44111a7c41c2e884a336cc4f461b3b2401", + "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2018-02-19T10:16:54+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/661f34d0bd3f1a7225ef491a70a020ad23a057a1", + "reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.0", + "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^2.0.1", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.0", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-xdebug": "^2.5.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2017-12-06T09:29:45+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2017-11-27T13:52:08+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26T11:10:40+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "791198a2c6254db10131eecfe8c06670700904db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", + "reference": "791198a2c6254db10131eecfe8c06670700904db", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2017-11-27T05:48:46+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "6.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "ff3a76a58ac293657808aefd58c8aaf05945f4d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ff3a76a58ac293657808aefd58c8aaf05945f4d9", + "reference": "ff3a76a58ac293657808aefd58c8aaf05945f4d9", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.3", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.0", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^5.2", + "phpunit/php-file-iterator": "^1.4", + "phpunit/php-text-template": "^1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^4.0", + "sebastian/comparator": "^2.0", + "sebastian/diff": "^1.4.3", + "sebastian/environment": "^3.0.2", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^1.1 || ^2.0", + "sebastian/object-enumerator": "^3.0.2", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2", + "phpunit/dbunit": "<3.0" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "^1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2017-08-03T13:59:28+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "2f789b59ab89669015ad984afa350c4ec577ade0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/2f789b59ab89669015ad984afa350c4ec577ade0", + "reference": "2f789b59ab89669015ad984afa350c4ec577ade0", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.5", + "php": "^7.0", + "phpunit/php-text-template": "^1.2.1", + "sebastian/exporter": "^3.0" + }, + "conflict": { + "phpunit/phpunit": "<6.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2017-08-03T14:08:16+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "20f84f468cb67efee293246e6a09619b891f55f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/20f84f468cb67efee293246e6a09619b891f55f0", + "reference": "20f84f468cb67efee293246e6a09619b891f55f0", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/diff": "^1.2", + "sebastian/exporter": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2017-03-03T06:26:08+00:00" + }, + { + "name": "sebastian/diff", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2017-05-22T07:24:03+00:00" + }, + { + "name": "sebastian/environment", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2017-07-01T08:51:00+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2017-04-03T13:19:02+00:00" + }, + { + "name": "sebastian/finder-facade", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/finder-facade.git", + "reference": "4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f", + "reference": "4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f", + "shasum": "" + }, + "require": { + "symfony/finder": "~2.3|~3.0|~4.0", + "theseer/fdomdocument": "~1.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", + "homepage": "https://github.com/sebastianbergmann/finder-facade", + "time": "2017-11-18T17:31:49+00:00" + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+00:00" + }, + { + "name": "sebastian/phpcpd", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpcpd.git", + "reference": "24d9a880deadb0b8c9680e9cfe78e30b704225db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/24d9a880deadb0b8c9680e9cfe78e30b704225db", + "reference": "24d9a880deadb0b8c9680e9cfe78e30b704225db", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-timer": ">=1.0.6", + "sebastian/finder-facade": "~1.1", + "sebastian/version": "~1.0|~2.0", + "symfony/console": "~2.7|^3.0", + "theseer/fdomdocument": "~1.4" + }, + "bin": [ + "phpcpd" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Copy/Paste Detector (CPD) for PHP code.", + "homepage": "https://github.com/sebastianbergmann/phpcpd", + "time": "2016-04-17T19:32:49+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2017-03-03T06:23:57+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "f9eaf037edf22fdfccf04cb0ab57ebcb1e166219" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/f9eaf037edf22fdfccf04cb0ab57ebcb1e166219", + "reference": "f9eaf037edf22fdfccf04cb0ab57ebcb1e166219", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "http://www.squizlabs.com/php-codesniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2017-06-14T01:23:49+00:00" + }, + { + "name": "symfony/config", + "version": "v3.4.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "05e10567b529476a006b00746c5f538f1636810e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/05e10567b529476a006b00746c5f538f1636810e", + "reference": "05e10567b529476a006b00746c5f538f1636810e", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/filesystem": "~2.8|~3.0|~4.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.3", + "symfony/finder": "<3.3" + }, + "require-dev": { + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/event-dispatcher": "~3.3|~4.0", + "symfony/finder": "~3.3|~4.0", + "symfony/yaml": "~3.0|~4.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "time": "2018-02-14T10:03:57+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v3.4.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "12e901abc1cb0d637a0e5abe9923471361d96b07" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/12e901abc1cb0d637a0e5abe9923471361d96b07", + "reference": "12e901abc1cb0d637a0e5abe9923471361d96b07", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/container": "^1.0" + }, + "conflict": { + "symfony/config": "<3.3.7", + "symfony/finder": "<3.3", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "psr/container-implementation": "1.0" + }, + "require-dev": { + "symfony/config": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "https://symfony.com", + "time": "2018-03-04T03:54:53+00:00" + }, + { + "name": "symfony/polyfill-php54", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php54.git", + "reference": "84e2b616c197ef400c6d0556a0606cee7c9e21d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/84e2b616c197ef400c6d0556a0606cee7c9e21d5", + "reference": "84e2b616c197ef400c6d0556a0606cee7c9e21d5", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php54\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-01-30T19:27:44+00:00" + }, + { + "name": "symfony/polyfill-php55", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php55.git", + "reference": "168371cb3dfb10e0afde96e7c2688be02470d143" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/168371cb3dfb10e0afde96e7c2688be02470d143", + "reference": "168371cb3dfb10e0afde96e7c2688be02470d143", + "shasum": "" + }, + "require": { + "ircmaxell/password-compat": "~1.0", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php55\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-01-30T19:27:44+00:00" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3532bfcd8f933a7816f3a0a59682fc404776600f", + "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-01-30T19:27:44+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "8eca20c8a369e069d4f4c2ac9895144112867422" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/8eca20c8a369e069d4f4c2ac9895144112867422", + "reference": "8eca20c8a369e069d4f4c2ac9895144112867422", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-01-31T17:43:24+00:00" + }, + { + "name": "symfony/polyfill-xml", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-xml.git", + "reference": "fcdfb6e64d21848ee65b6d5d0bc75fcb703b0c83" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-xml/zipball/fcdfb6e64d21848ee65b6d5d0bc75fcb703b0c83", + "reference": "fcdfb6e64d21848ee65b6d5d0bc75fcb703b0c83", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-php72": "~1.4" + }, + "type": "metapackage", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for xml's utf8_encode and utf8_decode functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-01-30T19:27:44+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v3.4.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "eb17cfa072cab26537ac37e9c4ece6c0361369af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/eb17cfa072cab26537ac37e9c4ece6c0361369af", + "reference": "eb17cfa072cab26537ac37e9c4ece6c0361369af", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "https://symfony.com", + "time": "2018-02-17T14:55:25+00:00" + }, + { + "name": "theseer/fdomdocument", + "version": "1.6.6", + "source": { + "type": "git", + "url": "https://github.com/theseer/fDOMDocument.git", + "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/6e8203e40a32a9c770bcb62fe37e68b948da6dca", + "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "lib-libxml": "*", + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "lead" + } + ], + "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", + "homepage": "https://github.com/theseer/fDOMDocument", + "time": "2017-06-30T11:53:12+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2017-04-07T12:08:54+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2018-01-29T19:49:41+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "phpmd/phpmd": 0 + }, + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "ext-ctype": "*", + "ext-curl": "*", + "ext-dom": "*", + "ext-gd": "*", + "ext-hash": "*", + "ext-iconv": "*", + "ext-intl": "*", + "ext-mbstring": "*", + "ext-mcrypt": "*", + "ext-openssl": "*", + "ext-pdo_mysql": "*", + "ext-simplexml": "*", + "ext-soap": "*", + "ext-spl": "*", + "ext-xsl": "*", + "ext-zip": "*", + "lib-libxml": "*" + }, + "platform-dev": [] +} From 05a87771aa3d2c2ba4983df4df9c54acc1761bbd Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Tue, 13 Mar 2018 12:47:24 -0500 Subject: [PATCH 059/668] MAGETWO-88934: Bundle products - Optimize bundle fetch - Implement new resolver interface for custom attribute metadata --- .../Model/ResourceModel/Option/Collection.php | 23 +- .../Products/DataProvider/ProductPlugin.php | 215 +++++++++++++++++- .../Resolver/CustomAttributeMetadata.php | 19 +- 3 files changed, 241 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Bundle/Model/ResourceModel/Option/Collection.php b/app/code/Magento/Bundle/Model/ResourceModel/Option/Collection.php index e701b4cf9cc1d..4d630331ed0e2 100644 --- a/app/code/Magento/Bundle/Model/ResourceModel/Option/Collection.php +++ b/app/code/Magento/Bundle/Model/ResourceModel/Option/Collection.php @@ -26,6 +26,11 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab */ protected $_selectionsAppended = false; + /** + * @var int[] + */ + private $productIds = []; + /** * Init model and resource model * @@ -94,6 +99,20 @@ public function joinValues($storeId) */ public function setProductIdFilter($productId) { + $this->productIds[] = $productId; + + return $this; + } + + /** + * Add product ids filter to select. + * + * @return $this + */ + protected function _beforeLoad() + { + parent::_beforeLoad(); + $productTable = $this->getTable('catalog_product_entity'); $linkField = $this->getConnection()->getAutoIncrementField($productTable); $this->getSelect()->join( @@ -101,8 +120,8 @@ public function setProductIdFilter($productId) 'cpe.'.$linkField.' = main_table.parent_id', [] )->where( - "cpe.entity_id = ?", - $productId + "cpe.entity_id in (?)", + $this->productIds ); return $this; diff --git a/app/code/Magento/BundleGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php b/app/code/Magento/BundleGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php index fe022aab62dda..690c4fd848e55 100644 --- a/app/code/Magento/BundleGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php +++ b/app/code/Magento/BundleGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php @@ -6,10 +6,14 @@ namespace Magento\BundleGraphQl\Model\Plugin\Model\Resolver\Products\DataProvider; +use Magento\Bundle\Api\Data\OptionInterface; use Magento\Bundle\Model\Product\Type as Bundle; use Magento\Framework\Api\SearchResultsInterface; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product; -use Magento\Bundle\Model\Product\OptionList; +use Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory; +use Magento\Bundle\Model\ResourceModel\Selection\Collection; +use Magento\Bundle\Api\Data\LinkInterfaceFactory; +use Magento\Bundle\Api\Data\LinkInterface; /** * Fetch bundle product object and set necessary extension attributes for search result @@ -17,16 +21,57 @@ class ProductPlugin { /** - * @var OptionList + * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface */ - private $productOptionList; + private $extensionAttributesJoinProcessor; /** - * @param OptionList $productOptionList + * @var \Magento\Bundle\Model\OptionFactory */ - public function __construct(OptionList $productOptionList) - { - $this->productOptionList = $productOptionList; + private $bundleOption; + + /** + * @var \Magento\Framework\Api\DataObjectHelper + */ + private $dataObjectHelper; + + /** + * @var \Magento\Bundle\Api\Data\OptionInterfaceFactory + */ + private $optionFactory; + + /** + * @var CollectionFactory + */ + private $linkCollectionFactory; + + /** + * @var LinkInterfaceFactory + */ + private $linkFactory; + + /** + * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor + * @param \Magento\Bundle\Model\OptionFactory $bundleOption + * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper + * @param \Magento\Bundle\Api\Data\OptionInterfaceFactory $optionFactory + * @param CollectionFactory $linkCollectionFactory + * @param LinkInterfaceFactory $linkFactory + */ + public function __construct( + \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, + \Magento\Bundle\Model\OptionFactory $bundleOption, + \Magento\Framework\Api\DataObjectHelper $dataObjectHelper, + \Magento\Bundle\Api\Data\OptionInterfaceFactory $optionFactory, + CollectionFactory $linkCollectionFactory, + LinkInterfaceFactory $linkFactory + ) { + $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; + $this->bundleOption = $bundleOption; + $this->dataObjectHelper = $dataObjectHelper; + $this->optionFactory = $optionFactory; + $this->linkCollectionFactory = $linkCollectionFactory; + $this->linkFactory = $linkFactory; } /** @@ -39,14 +84,166 @@ public function __construct(OptionList $productOptionList) */ public function afterGetList(Product $subject, SearchResultsInterface $result) { + $products = []; + $productList = $result->getItems(); + /** @var \Magento\Catalog\Model\Product $product */ foreach ($result->getItems() as $product) { if ($product->getTypeId() === Bundle::TYPE_CODE) { + $products[] = $product; + } + } + + if (empty($products)) { + return $result; + } + + $options = $this->getOptionsCollectionByStoreId($products); + + $options = $this->hydrateLinks($options); + + foreach ($options as $parentId => $optionList) { + foreach ($productList as $product) { + if (!(int)$product->getId() === $parentId) { + continue; + } $extensionAttributes = $product->getExtensionAttributes(); - $options = $this->productOptionList->getItems($product); - $extensionAttributes->setBundleProductOptions($options); + $extensionAttributes->setBundleProductOptions($optionList); $product->setExtensionAttributes($extensionAttributes); } } + return $result; } + + /** + * Retrieve bundle option collection + * + * @param \Magento\Catalog\Model\Product[] $products + * @return array + */ + private function getOptionsCollectionByStoreId(array $products) + { + /** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionsCollection */ + $optionsCollection = $this->bundleOption->create()->getResourceCollection(); + // All products in collection will have same store id. + $optionsCollection->joinValues($products[0]->getStoreId()); + foreach ($products as $product) { + $optionsCollection->setProductIdFilter($product->getEntityId()); + } + $optionsCollection->setPositionOrder(); + + $this->extensionAttributesJoinProcessor->process($optionsCollection); + if (empty($optionsCollection->getData())) { + return []; + } + + $options = []; + /** @var \Magento\Bundle\Model\Option $option */ + foreach ($optionsCollection as $option) { + /** @var OptionInterface $optionInterface */ + $optionInterface = $this->optionFactory->create(); + foreach ($products as $product) { + if ((int)$product->getId() !== (int)$option->getParentId()) { + continue; + } + + $this->dataObjectHelper->populateWithArray( + $optionInterface, + $option->getData(), + \Magento\Bundle\Api\Data\OptionInterface::class + ); + $optionInterface->setOptionId($option->getOptionId()) + ->setTitle($option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle()) + ->setDefaultTitle($option->getDefaultTitle()) + ->setSku($product->getSku()); + break; + } + + if ($optionInterface->getOptionId() === null) { + continue; + } + + if (!isset($options[$option->getParentId()])) { + $options[(int)$option->getParentId()] = []; + } + + $options[(int)$option->getParentId()][] = $optionInterface; + } + + return $options; + } + + /** + * Hydrate links for input options + * + * @param array $optionsMap + * @return array + */ + private function hydrateLinks(array $optionsMap) + { + $parentIds = []; + $optionIds = []; + foreach ($optionsMap as $parentId => $optionList) { + $parentIds[] = $parentId; + /** @var OptionInterface $option */ + foreach ($optionList as $option) { + if (in_array($option->getOptionId(), $optionIds)) { + continue; + } + + $optionsIds = []; + } + } + + /** @var Collection $linkCollection */ + $linkCollection = $this->linkCollectionFactory->create(); + $linkCollection->setOptionIdsFilter($optionsIds); + $field = 'parent_product_id'; + foreach ($linkCollection->getSelect()->getPart('from') as $tableAlias => $data) { + if ($data['tableName'] == $linkCollection->getTable('catalog_product_bundle_selection')) { + $field = $tableAlias . '.' . $field; + } + } + + $linkCollection->getSelect() + ->where($field . ' IN (?)', $parentIds); + + $productLinksMap = []; + + /** @var \Magento\Catalog\Model\Product $selection $link */ + foreach ($linkCollection as $link) { + $selectionPriceType = $link->getSelectionPriceType(); + $selectionPrice = $link->getSelectionPriceValue(); + /** @var LinkInterface $productLink */ + $productLink = $this->linkFactory->create(); + $this->dataObjectHelper->populateWithArray( + $productLink, + $link->getData(), + \Magento\Bundle\Api\Data\LinkInterface::class + ); + $productLink->setIsDefault($link->getIsDefault()) + ->setId($link->getSelectionId()) + ->setQty($link->getSelectionQty()) + ->setCanChangeQuantity($link->getSelectionCanChangeQty()) + ->setPrice($selectionPrice) + ->setPriceType($selectionPriceType); + if (!isset($productLinksMap[$productLink->getOptionId()])) { + $productLinksMap[$productLink->getOptionId()] = []; + } + $productLinksMap[$productLink->getOptionId()][] = $productLink; + } + + foreach ($productLinksMap as $optionId => $productLinkList) { + foreach ($optionsMap as $parentId => $optionsList) { + /** @var OptionInterface $option */ + foreach ($optionsList as $optionKey => $option) { + if ((int)$option->getOptionId() === (int)$optionId) { + $optionsMap[$parentId][$optionKey]->setProductLinks($productLinkList); + } + } + } + } + + return $optionsMap; + } } diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php b/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php index 8d8a8f0db2c5c..ca09cde3288fc 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php @@ -6,14 +6,15 @@ namespace Magento\EavGraphQl\Model\Resolver; +use GraphQL\Type\Definition\ResolveInfo; use Magento\Framework\Exception\InputException; -use Magento\Framework\GraphQl\Argument\ArgumentValueInterface; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\ArgumentInterface; +use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; -use Magento\GraphQl\Model\ResolverInterface; -use \Magento\GraphQl\Model\ResolverContextInterface; use Magento\EavGraphQl\Model\Resolver\Query\Type; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; /** * Resolve data for custom attribute metadata requests @@ -36,12 +37,12 @@ public function __construct(Type $type) /** * {@inheritDoc} */ - public function resolve(array $args, ResolverContextInterface $context) + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) { $attributes['items'] = null; /** @var ArgumentInterface $attributeInputs */ $attributeInputs = $args['attributes']; - foreach ($attributeInputs->getValue() as $attribute) { + foreach ($attributeInputs as $attribute) { if (!isset($attribute['attribute_code']) || !isset($attribute['entity_type'])) { $attributes['items'][] = $this->createInputException($attribute); continue; @@ -56,6 +57,14 @@ public function resolve(array $args, ResolverContextInterface $context) ) ); continue; + } catch (LocalizedException $exception) { + $attributes['items'][] = new GraphQlInputException( + __( + 'Invalid entity_type specified: %1', + [$attribute['entity_type']] + ) + ); + continue; } if (empty($type)) { From cec94793a3d4a57592276572dac7f075e8d367b5 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Tue, 13 Mar 2018 13:44:52 -0500 Subject: [PATCH 060/668] MAGETWO-88934: Implement new resolver for customer --- .../Magento/CustomerGraphQl/Model/Resolver/Customer.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php index dc875a7bb37c4..3c8c41871598c 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php @@ -6,11 +6,12 @@ namespace Magento\CustomerGraphQl\Model\Resolver; +use GraphQL\Type\Definition\ResolveInfo; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; -use Magento\GraphQl\Model\ResolverInterface; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\GraphQl\Model\ResolverContextInterface; /** @@ -35,8 +36,9 @@ public function __construct( /** * {@inheritdoc} */ - public function resolve(array $args, ResolverContextInterface $context) + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) { + /** @var ResolverContextInterface $context */ if ((!$context->getUserId()) || $context->getUserType() == 4) { throw new GraphQlAuthorizationException( __( From ce4b85bad236708c0377424a17e11a82161533a0 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Tue, 13 Mar 2018 14:07:13 -0500 Subject: [PATCH 061/668] MAGETWO-88934: Implement new resolver for UrlRewrite --- .../UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php index aaf0a22252aba..aab5dec66669a 100644 --- a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php +++ b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php @@ -6,9 +6,9 @@ namespace Magento\UrlRewriteGraphQl\Model\Resolver; -use Magento\GraphQl\Model\ResolverContextInterface; -use Magento\GraphQl\Model\ResolverInterface; -use Magento\GraphQl\Model\ContextInterface; +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\UrlRewrite\Model\UrlFinderInterface; use Magento\Store\Model\StoreManagerInterface; @@ -42,10 +42,10 @@ public function __construct( /** * {@inheritdoc} */ - public function resolve(array $args, ResolverContextInterface $context) + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) { if (isset($args['url'])) { - $urlRewrite = $this->findCanonicalUrl($args['url']->getValue()); + $urlRewrite = $this->findCanonicalUrl($args['url']); if ($urlRewrite) { return [ 'id' => $urlRewrite->getEntityId(), From 12d575159666f1cef57c4afc26546fdd2a42b4c7 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@magento.com> Date: Tue, 13 Mar 2018 19:37:25 -0500 Subject: [PATCH 062/668] MAGETWO-89178: Create integration or functional test - Added additional validation to check graphQL response for errors and trace --- .../ExceptionFormatterDefaultModeTest.php | 27 +++++++ .../GraphQl/Eav/ExceptionFormatterTest.php | 79 ------------------- .../Controller/GraphQlControllerTest.php | 75 +++++++++++++++--- 3 files changed, 91 insertions(+), 90 deletions(-) delete mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Eav/ExceptionFormatterTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ExceptionFormatterDefaultModeTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ExceptionFormatterDefaultModeTest.php index 6be7f9929b424..8c939e714819f 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ExceptionFormatterDefaultModeTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ExceptionFormatterDefaultModeTest.php @@ -111,4 +111,31 @@ public function testAttributeWithNoAttributeCodeInputException() $this->graphQlQuery($query); } + + public function testInvalidEntityTypeException() + { + $query + = <<<QUERY + { + customAttributeMetadata(attributes:[ + { + attribute_code:"sku" + entity_type:"invalid" + } + ]) + { + items{ + attribute_code + attribute_type + entity_type + } + } + } +QUERY; + $this->expectException(\Exception::class); + + $this->expectExceptionMessage('Invalid entity_type specified: invalid'); + + $this->graphQlQuery($query); + } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Eav/ExceptionFormatterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Eav/ExceptionFormatterTest.php deleted file mode 100644 index 742b06ae0eea8..0000000000000 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Eav/ExceptionFormatterTest.php +++ /dev/null @@ -1,79 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\GraphQl\Eav; - -use Magento\Framework\App\State; -use Magento\TestFramework\ObjectManager; -use Magento\TestFramework\TestCase\GraphQlAbstract; - -class ExceptionFormatterTest extends GraphQlAbstract -{ - /** @var string */ - private $mageMode; - - /** - * @var \Magento\TestFramework\ObjectManager - */ - private $objectManager; - - protected function setUp() - { - parent::setUp(); - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - - $this->mageMode = $this->objectManager->get(State::class)->getMode(); - } - - protected function tearDown() - { - $this->objectManager->get(State::class)->setMode($this->mageMode); - } - - /** - * @param string $mageMode - */ - private function setDeveloperMode($mageMode = State::MODE_DEVELOPER) - { - $this->objectManager->get(State::class)->setMode($mageMode); - echo 'mageMode:'. $mageMode; - } - - public function testInvalidEntityTypeExceptionInDeveloperMode($mageMode = State::MODE_DEVELOPER) - { - $this->markTestSkipped( - "Current infrastructure cannot switch out of produciton mode, which is required for this test." - ); - $this->setDeveloperMode(); - $this->objectManager->get(State::class)->setMode($mageMode); - - if (!$this->cleanCache()) { - $this->fail('Cache could not be cleaned properly.'); - } - $query - = <<<QUERY - { - customAttributeMetadata(attributes:[ - { - attribute_code:"sku" - entity_type:"invalid" - } - ]) - { - items{ - attribute_code - attribute_type - entity_type - } - } - } -QUERY; - $this->expectException(\Exception::class); - - $this->expectExceptionMessage('Invalid entity_type specified: invalid'); - - $this->graphQlQuery($query); - } -} diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php index 376e9e10797be..7d9e1ccbc1add 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php @@ -11,6 +11,7 @@ use Magento\Framework\App\Request\Http; use Magento\Framework\App\RequestInterface; use Magento\Framework\App\State; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\HttpHeaderProcessorInterface; use Magento\Framework\GraphQl\HttpRequestProcessor; use Magento\Framework\Serialize\SerializerInterface; @@ -37,7 +38,7 @@ class GraphQlControllerTest extends \PHPUnit\Framework\TestCase */ private $objectManager; - /** @var \Magento\Framework\App\Request\Http $request */ + /** @var \Magento\Framework\App\Request\Http $request */ private $request; /** @@ -45,11 +46,7 @@ class GraphQlControllerTest extends \PHPUnit\Framework\TestCase */ private $graphql; - /** @var array */ - private $serverArray; - - - /** @var SerializerInterface */ + /** @var SerializerInterface */ private $jsonSerializer; protected function setUp() @@ -85,17 +82,17 @@ public function testDispatch() } QUERY; $postData = [ - 'query' => $query, - 'variables'=> null, - 'operationName'=> null + 'query' => $query, + 'variables' => null, + 'operationName' => null ]; /** @var Http $request */ $request = $this->objectManager->get(\Magento\Framework\App\Request\Http::class); $request->setPathInfo('/graphql'); $request->setContent(json_encode($postData)); $headers = $this->objectManager->create(\Zend\Http\Headers::class) - ->addHeaders(['Content-Type' => 'application/json'] - ); + ->addHeaders(['Content-Type' => 'application/json'] + ); $request->setHeaders($headers); $response = $this->graphql->dispatch($request); $output = $this->jsonSerializer->unserialize($response->getContent()); @@ -103,4 +100,60 @@ public function testDispatch() $this->assertEquals($output['data']['products']['items'][0]['sku'], $product->getSku()); $this->assertEquals($output['data']['products']['items'][0]['name'], $product->getName()); } + + + public function testOutputErrorsWithMessageCategoryAndTrace() + { + $query + = <<<QUERY + { + customAttributeMetadata(attributes:[ + { + attribute_code:"sku" + entity_type:"invalid" + } + ]) + { + items{ + attribute_code + attribute_type + entity_type + } + } + } +QUERY; + + + $postData = [ + 'query' => $query, + 'variables' => null, + 'operationName' => null + ]; + /** @var Http $request */ + $request = $this->objectManager->get(\Magento\Framework\App\Request\Http::class); + $request->setPathInfo('/graphql'); + $request->setContent(json_encode($postData)); + $headers = $this->objectManager->create(\Zend\Http\Headers::class) + ->addHeaders(['Content-Type' => 'application/json'] + ); + $request->setHeaders($headers); + $response = $this->graphql->dispatch($request); + $outputResponse = $this->jsonSerializer->unserialize($response->getContent()); + if(isset($outputResponse['errors'][0])) { + if(is_array($outputResponse['errors'][0])) { + foreach($outputResponse['errors'] as $error) { + $this->assertEquals($error['category'], \Magento\Framework\GraphQl\Exception\GraphQlInputException::EXCEPTION_CATEGORY); + if (isset($error['message'])) { + $this->assertEquals($error['message'], 'Invalid entity_type specified: invalid'); + } + if(isset($error['trace'])) + { + if(is_array($error['trace'])) + $this->assertNotEmpty($error['trace']); + } + } + } + } + } } + From a50b8b292e80cbf4578f8b3e77220727769cf2ae Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 13 Mar 2018 20:47:27 -0500 Subject: [PATCH 063/668] MAGETWO-89031: Make all graphql methods to return strict type - wrapped type processor --- .../GraphQl/Config/Data/Argument.php | 4 +- .../Framework/GraphQl/Config/Data/Field.php | 4 +- .../GraphQl/Config/Data/FieldInterface.php | 35 +++++ .../Config/Data/OutputFieldInterface.php | 28 ++++ .../Config/Data/WrappedTypeProcessor.php | 147 ++++++++++++++++++ .../GraphQl/Type/Definition/ListOfType.php | 2 +- .../GraphQl/Type/Definition/NonNull.php | 2 +- .../GraphQl/Type/Definition/ScalarTypes.php | 12 +- .../Type/Definition/WrappedTypeInterface.php | 16 ++ .../GraphQl/Type/Input/InputMapper.php | 38 +++-- .../GraphQl/Type/Input/InputObjectType.php | 51 ++---- .../Output/ElementMapper/Formatter/Fields.php | 59 ++----- 12 files changed, 289 insertions(+), 109 deletions(-) create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Data/FieldInterface.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Data/OutputFieldInterface.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Data/WrappedTypeProcessor.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Type/Definition/WrappedTypeInterface.php diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php index c620ef762992a..c450c3fdf2919 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php @@ -12,7 +12,7 @@ * * Arguments of a type in GraphQL are used to gather client input to affect how a query will return data. */ -class Argument +class Argument implements FieldInterface { /** * @var string @@ -159,7 +159,7 @@ public function getDescription() : string * * @return string|null */ - public function getDefault() //: ?string + public function getDefault() : ?string { return $this->default; } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php index 730f6aeb7e5ae..2c9f3a5f90617 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php @@ -10,7 +10,7 @@ /** * Structured data object of a GraphQL field. Fields are used to describe possible values for a type/interface. */ -class Field +class Field implements OutputFieldInterface { /** * @var string @@ -138,7 +138,7 @@ public function getArguments() : array * * @return string|null */ - public function getDescription() + public function getDescription() : string { return $this->description; } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/FieldInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/FieldInterface.php new file mode 100644 index 0000000000000..c81f7539fc836 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/FieldInterface.php @@ -0,0 +1,35 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Framework\GraphQl\Config\Data; + +/** + * Defines contracts for general fields data objects that, combined, represent a configured GraphQL schema. + */ +interface FieldInterface extends StructureInterface +{ + /** + * Get the type's configured name. + * + * @return string + */ + public function getType() : string; + + /** + * Return true if argument is a list of input items, otherwise false if it is a single object/scalar. + * + * @return bool + */ + public function isList(): bool; + + /** + * Return true if argument is required when invoking the query where the argument is specified. False otherwise. + * + * @return bool + */ + public function isRequired(): bool; +} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/OutputFieldInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/OutputFieldInterface.php new file mode 100644 index 0000000000000..632495887afe3 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/OutputFieldInterface.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Framework\GraphQl\Config\Data; + +/** + * Defines contracts for output fields data objects that, combined, represent a configured GraphQL schema. + */ +interface OutputFieldInterface extends FieldInterface +{ + /** + * Get the resolver for a given field. If no resolver is specified, return an empty string. + * + * @return string + */ + public function getResolver() : string; + + /** + * Get the list of arguments configured for the field. Return an empty array if no arguments are configured. + * + * @return Argument[] + */ + public function getArguments() : array; +} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/WrappedTypeProcessor.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/WrappedTypeProcessor.php new file mode 100644 index 0000000000000..b68beec8bfda0 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/WrappedTypeProcessor.php @@ -0,0 +1,147 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Framework\GraphQl\Config\Data; + +use Magento\Framework\GraphQl\Type\Definition\TypeInterface; +use Magento\Framework\GraphQl\TypeFactory; +use Magento\Framework\GraphQl\Type\Definition\ScalarTypes; + +/** + * Factory for @see TypeInterface implementations + */ +class WrappedTypeProcessor +{ + /** + * @var ScalarTypes + */ + private $scalarTypes; + + /** + * @var TypeFactory + */ + private $typeFactory; + + /** + * @param TypeFactory $typeFactory + * @param ScalarTypes $scalarTypes + */ + public function __construct(TypeFactory $typeFactory, ScalarTypes $scalarTypes) + { + $this->typeFactory = $typeFactory; + $this->scalarTypes = $scalarTypes; + } + + /** + * Determine the wrapped type from field + * + * Examples: nullable or required + * + * @param FieldInterface $field + * @param TypeInterface $object + * @return TypeInterface + */ + public function processWrappedType(FieldInterface $field, TypeInterface $object = null) : TypeInterface + { + return $this->processIsNullable($field, $this->processIsList($field, $object)); + } + + /** + * Determine the wrapped type from field. + * + * Examples: nullable or required. + * + * @param FieldInterface $field + * @param TypeInterface $object + * @return \GraphQL\Type\Definition\Type + */ + public function processScalarWrappedType( + FieldInterface $field, + TypeInterface $object = null + ) : \GraphQL\Type\Definition\Type { + if (!$object) { + $object = $this->scalarTypes->getScalarTypeInstance($field->getType()); + } + return $this->processScalarIsNullable($field, $this->processScalarIsList($field, $object)); + } + + /** + * Return passed in type wrapped as a non null type if definition determines necessary. + * + * @param FieldInterface $field + * @param TypeInterface $object + * @return TypeInterface + */ + private function processIsNullable(FieldInterface $field, TypeInterface $object = null) : TypeInterface + { + if ($field->isRequired()) { + return $this->typeFactory->createNonNull($object); + } + return $object; + } + + /** + * Return passed in type wrapped as a list if definition determines necessary. + * + * @param FieldInterface $field + * @param TypeInterface $object + * @return TypeInterface + */ + private function processIsList(FieldInterface $field, TypeInterface $object = null) : TypeInterface + { + if ($field->isList()) { + if ($field instanceof \Magento\Framework\GraphQl\Config\Data\Argument) { + if ($field->areItemsRequired()) { + $object = $this->typeFactory->createNonNull($object); + } + } + return $this->typeFactory->createList($object); + } + return $object; + } + + /** + * Return passed in scalar type wrapped as a non null type if definition determines necessary. + * + * @param FieldInterface $field + * @param \GraphQL\Type\Definition\Type $object + * @return \GraphQL\Type\Definition\Type + */ + private function processScalarIsNullable( + FieldInterface $field, + \GraphQL\Type\Definition\Type $object = null + ) : \GraphQL\Type\Definition\Type { + $object = $object ?: $this->scalarTypes->getScalarTypeInstance($field->getType()); + if ($field->isRequired()) { + return $this->scalarTypes->createNonNull($object); + } + return $object; + } + + /** + * Return passed in scalar type wrapped as a list if definition determines necessary. + * + * @param FieldInterface $field + * @param \GraphQL\Type\Definition\Type $object + * @return \GraphQL\Type\Definition\Type + */ + private function processScalarIsList( + FieldInterface $field, + \GraphQL\Type\Definition\Type $object = null + ) : \GraphQL\Type\Definition\Type { + $object = $object ?: $this->scalarTypes->getScalarTypeInstance($field->getType()); + if ($field->isList()) { + if ($field instanceof \Magento\Framework\GraphQl\Config\Data\Argument) { + if ($field->areItemsRequired()) { + $object = $this->scalarTypes->createNonNull($object); + } + } + return $this->scalarTypes->createList($object); + } + return $object; + } +} diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ListOfType.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ListOfType.php index 01b7ac41f5595..89778d339ec1d 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ListOfType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ListOfType.php @@ -10,7 +10,7 @@ /** * Wrapper for GraphQl ListOfType */ -class ListOfType extends \GraphQL\Type\Definition\ListOfType implements InputType, OutputType +class ListOfType extends \GraphQL\Type\Definition\ListOfType implements WrappedTypeInterface, InputType, OutputType { } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/NonNull.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/NonNull.php index 025d0318a4365..2327f95bd3b46 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/NonNull.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/NonNull.php @@ -10,7 +10,7 @@ /** * Wrapper for GraphQl NonNull */ -class NonNull extends \GraphQL\Type\Definition\NonNull implements InputType, OutputType +class NonNull extends \GraphQL\Type\Definition\NonNull implements WrappedTypeInterface, InputType, OutputType { } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php index e272432d7a556..dcc925f7db2c1 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php @@ -24,10 +24,10 @@ public function hasScalarTypeClass(string $typeName) : bool /** * @param string $typeName - * @return \GraphQL\Type\Definition\ScalarType + * @return \GraphQL\Type\Definition\ScalarType|\GraphQL\Type\Definition\Type * @throws \LogicException */ - public function getScalarTypeInstance(string $typeName) : \GraphQL\Type\Definition\ScalarType + public function getScalarTypeInstance(string $typeName) : \GraphQL\Type\Definition\Type { $internalTypes = \GraphQL\Type\Definition\Type::getInternalTypes(); if ($this->hasScalarTypeClass($typeName)) { @@ -40,10 +40,10 @@ public function getScalarTypeInstance(string $typeName) : \GraphQL\Type\Definiti /** * Create an list array type * - * @param \GraphQL\Type\Definition\ScalarType $definedType + * @param \GraphQL\Type\Definition\ScalarType|\GraphQL\Type\Definition\Type $definedType * @return ListOfType */ - public function createList(\GraphQL\Type\Definition\ScalarType $definedType) : ListOfType + public function createList(\GraphQL\Type\Definition\Type $definedType) : ListOfType { return new ListOfType($definedType); } @@ -51,10 +51,10 @@ public function createList(\GraphQL\Type\Definition\ScalarType $definedType) : L /** * Create a non null type * - * @param \GraphQL\Type\Definition\ScalarType $definedType + * @param \GraphQL\Type\Definition\ScalarType|\GraphQL\Type\Definition\Type $definedType * @return NonNull */ - public function createNonNull(\GraphQL\Type\Definition\ScalarType $definedType) : NonNull + public function createNonNull(\GraphQL\Type\Definition\Type $definedType) : NonNull { return new NonNull($definedType); } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/WrappedTypeInterface.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/WrappedTypeInterface.php new file mode 100644 index 0000000000000..622c2c2b9623c --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/WrappedTypeInterface.php @@ -0,0 +1,16 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Framework\GraphQl\Type\Definition; + +/** + * Interface for GraphQl WrappedType used to wrap other types like array or not null + */ +interface WrappedTypeInterface extends \GraphQL\Type\Definition\WrappingType, TypeInterface +{ + +} diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php index 2325fc7fe485e..c6ce7fc25b4ae 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php @@ -12,6 +12,7 @@ use Magento\Framework\GraphQl\Type\Definition\InputType; use Magento\Framework\GraphQl\TypeFactory; use Magento\Framework\GraphQl\Type\Definition\ScalarTypes; +use Magento\Framework\GraphQl\Config\Data\WrappedTypeProcessor; /** * Class OutputMapper @@ -38,22 +39,30 @@ class InputMapper */ private $scalarTypes; + /** + * @var WrappedTypeProcessor + */ + private $wrappedTypeProcessor; + /** * @param InputFactory $inputFactory * @param ConfigInterface $config * @param TypeFactory $typeFactory * @param ScalarTypes $scalarTypes + * @param WrappedTypeProcessor $wrappedTypeProcessor */ public function __construct( InputFactory $inputFactory, ConfigInterface $config, TypeFactory $typeFactory, - ScalarTypes $scalarTypes + ScalarTypes $scalarTypes, + WrappedTypeProcessor $wrappedTypeProcessor ) { $this->inputFactory = $inputFactory; $this->config = $config; $this->typeFactory = $typeFactory; $this->scalarTypes = $scalarTypes; + $this->wrappedTypeProcessor = $wrappedTypeProcessor; } /** @@ -67,25 +76,22 @@ public function getRepresentation(Argument $argument) : array $type = $argument->getType(); $calculateDefault = true; if ($this->scalarTypes->hasScalarTypeClass($type)) { - $instance = $this->scalarTypes->getScalarTypeInstance($type); - if ($argument->isList()) { - $instance = $argument->areItemsRequired() ? $this->scalarTypes->createNonNull($instance) : $instance; - $instance = $this->scalarTypes->createList($instance); - } - if ($argument->isRequired()) { - $instance = $this->scalarTypes->createNonNull($instance); - } + //$instance = $this->scalarTypes->getScalarTypeInstance($type); + $instance = $this->wrappedTypeProcessor->processScalarWrappedType($argument); + +// if ($argument->isList()) { +// $instance = $argument->areItemsRequired() ? $this->scalarTypes->createNonNull($instance) : $instance; +// $instance = $this->scalarTypes->createList($instance); +// } +// +// if ($argument->isRequired()) { +// $instance = $this->scalarTypes->createNonNull($instance); +// } } else { $configElement = $this->config->getTypeStructure($type); $instance = $this->inputFactory->create($configElement); $calculateDefault = false; - if ($argument->isList()) { - $instance = $argument->areItemsRequired() ? $this->typeFactory->createNonNull($instance) : $instance; - $instance = $this->typeFactory->createList($instance); - } - if ($argument->isRequired()) { - $instance = $this->typeFactory->createNonNull($instance); - } + $instance = $this->wrappedTypeProcessor->processWrappedType($argument, $instance); } $calculatedArgument = [ diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php index 15821e598b70b..8c09aff797354 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php @@ -13,6 +13,7 @@ use Magento\Framework\GraphQl\Type\Definition\TypeInterface; use Magento\Framework\GraphQl\TypeFactory; use Magento\Framework\GraphQl\Type\Definition\ScalarTypes; +use Magento\Framework\GraphQl\Config\Data\WrappedTypeProcessor; /** * Class InputObjectType @@ -29,40 +30,42 @@ class InputObjectType extends \Magento\Framework\GraphQl\Type\Definition\InputOb */ private $scalarTypes; + /** + * @var WrappedTypeProcessor + */ + private $wrappedTypeProcessor; + /** * @param InputMapper $inputMapper * @param TypeStructure $structure * @param TypeFactory $typeFactory * @param ScalarTypes $scalarTypes + * @param WrappedTypeProcessor $wrappedTypeProcessor */ public function __construct( InputMapper $inputMapper, TypeStructure $structure, TypeFactory $typeFactory, - ScalarTypes $scalarTypes + ScalarTypes $scalarTypes, + WrappedTypeProcessor $wrappedTypeProcessor ) { $this->typeFactory = $typeFactory; $this->scalarTypes = $scalarTypes; + $this->wrappedTypeProcessor = $wrappedTypeProcessor; $config = [ 'name' => $structure->getName(), 'description' => $structure->getDescription() ]; foreach ($structure->getFields() as $field) { if ($this->scalarTypes->hasScalarTypeClass($field->getType())) { - $type = $this->scalarTypes->getScalarTypeInstance($field->getType()); - if ($field->isList()) { - $type = $this->scalarTypes->createList($type); - } - if ($field->isRequired()) { - $type = $this->scalarTypes->createNonNull($type); - } + $type = $type = $this->wrappedTypeProcessor->processScalarWrappedType($field); } else { if ($field->getType() == $structure->getName()) { $type = $this; } else { $type = $inputMapper->getFieldRepresentation($field->getType()); } - $type = $this->processIsNullable($field, $this->processIsList($field, $type)); + $type = $this->wrappedTypeProcessor->processWrappedType($field, $type); } $config['fields'][$field->getName()] = [ @@ -72,34 +75,4 @@ public function __construct( } parent::__construct($config); } - - /** - * Return passed in type wrapped as a non null type if definition determines necessary. - * - * @param Field $field - * @param InputType $object - * @return TypeInterface|InputType - */ - private function processIsNullable(Field $field, InputType $object) : TypeInterface - { - if ($field->isRequired()) { - return $this->typeFactory->createNonNull($object); - } - return $object; - } - - /** - * Return passed in type wrapped as a list if definition determines necessary. - * - * @param Field $field - * @param InputType $object - * @return TypeInterface|InputType - */ - private function processIsList(Field $field, InputType $object) : TypeInterface - { - if ($field->isList()) { - return $this->typeFactory->createList($object); - } - return $object; - } } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php index 7648913297c9d..a3b8f77190538 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php @@ -20,6 +20,7 @@ use Magento\Framework\ObjectManagerInterface; use Magento\Framework\GraphQl\Config\FieldConfig; use Magento\Framework\GraphQl\Type\Definition\ScalarTypes; +use Magento\Framework\GraphQl\Config\Data\WrappedTypeProcessor; /** * Formats all fields configured for given type structure, if any. @@ -61,6 +62,11 @@ class Fields implements FormatterInterface */ private $scalarTypes; + /** + * @var WrappedTypeProcessor + */ + private $wrappedTypeProcessor; + /** * @param ObjectManagerInterface $objectManager * @param FieldConfig $fieldConfig @@ -69,6 +75,7 @@ class Fields implements FormatterInterface * @param InputMapper $inputMapper * @param TypeFactory $typeFactory * @param ScalarTypes $scalarTypes + * @param WrappedTypeProcessor $wrappedTypeProcessor */ public function __construct( ObjectManagerInterface $objectManager, @@ -77,7 +84,8 @@ public function __construct( OutputMapper $outputMapper, InputMapper $inputMapper, TypeFactory $typeFactory, - ScalarTypes $scalarTypes + ScalarTypes $scalarTypes, + WrappedTypeProcessor $wrappedTypeProcessor ) { $this->objectManager = $objectManager; $this->fieldConfig = $fieldConfig; @@ -86,6 +94,7 @@ public function __construct( $this->inputMapper = $inputMapper; $this->typeFactory = $typeFactory; $this->scalarTypes = $scalarTypes; + $this->wrappedTypeProcessor = $wrappedTypeProcessor; } /** @@ -97,18 +106,14 @@ public function format(StructureInterface $typeStructure, OutputType $outputType $config = []; /** @var Field $field */ foreach ($typeStructure->getFields() as $field) { - if ($typeStructure->getName() == $field->getType()) { - $type = $outputType; - } elseif ($this->scalarTypes->hasScalarTypeClass($field->getType())) { - if ($field->isList()) { - $type = new \Magento\Framework\GraphQl\Type\Definition\ListOfType( - $this->scalarTypes->getScalarTypeInstance($field->getType()) - ); + if ($this->scalarTypes->hasScalarTypeClass($field->getType())) { + $type = $this->wrappedTypeProcessor->processScalarWrappedType($field); + } else { + if ($typeStructure->getName() == $field->getType()) { + $type = $outputType; } else { - $type = $this->scalarTypes->getScalarTypeInstance($field->getType()); + $type = $this->getFieldType($typeStructure, $field, $outputType); } - } else { - $type = $this->getFieldType($typeStructure, $field, $outputType); } $config['fields'][$field->getName()] = [ 'name' => $field->getName(), @@ -133,36 +138,6 @@ function ($value, $args, $context, $info) use ($resolver, $field) { return $config; } - /** - * Return passed in type wrapped as a non null type if definition determines necessary. - * - * @param Field $field - * @param OutputType $object - * @return OutputType - */ - private function processIsNullable(Field $field, OutputType $object) : OutputType - { - if ($field->isRequired()) { - return $this->typeFactory->createNonNull($object); - } - return $object; - } - - /** - * Return passed in type wrapped as a list if definition determines necessary. - * - * @param Field $field - * @param OutputType $object - * @return OutputType - */ - private function processIsList(Field $field, OutputType $object) : OutputType - { - if ($field->isList()) { - return $this->typeFactory->createList($object); - } - return $object; - } - /** * Determine field's type based on configured attributes. * @@ -179,7 +154,7 @@ private function getFieldType(StructureInterface $typeStructure, Field $field, O $type = $this->outputMapper->getTypeObject($field->getType()); } - $type = $this->processIsNullable($field, $this->processIsList($field, $type)); + $type = $this->wrappedTypeProcessor->processWrappedType($field, $type); return $type; } From 22c0292a407ec915a91da86514654de0bd55b93c Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 13 Mar 2018 20:56:24 -0500 Subject: [PATCH 064/668] MAGETWO-89031: Make all graphql methods to return strict type - refactor --- .../GraphQl/Type/Input/InputMapper.php | 22 ++------------ .../Output/ElementMapper/Formatter/Fields.php | 30 +++++-------------- 2 files changed, 10 insertions(+), 42 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php index c6ce7fc25b4ae..84b6ac28070f9 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php @@ -74,23 +74,11 @@ public function __construct( public function getRepresentation(Argument $argument) : array { $type = $argument->getType(); - $calculateDefault = true; if ($this->scalarTypes->hasScalarTypeClass($type)) { - //$instance = $this->scalarTypes->getScalarTypeInstance($type); $instance = $this->wrappedTypeProcessor->processScalarWrappedType($argument); - -// if ($argument->isList()) { -// $instance = $argument->areItemsRequired() ? $this->scalarTypes->createNonNull($instance) : $instance; -// $instance = $this->scalarTypes->createList($instance); -// } -// -// if ($argument->isRequired()) { -// $instance = $this->scalarTypes->createNonNull($instance); -// } } else { $configElement = $this->config->getTypeStructure($type); $instance = $this->inputFactory->create($configElement); - $calculateDefault = false; $instance = $this->wrappedTypeProcessor->processWrappedType($argument, $instance); } @@ -99,7 +87,7 @@ public function getRepresentation(Argument $argument) : array 'description' => $argument->getDescription() ]; - if ($calculateDefault && $argument->getDefault() !== null) { + if (!$this->scalarTypes->hasScalarTypeClass($type) && $argument->getDefault() !== null) { switch ($argument->getType()) { case 'Int': $calculatedArgument['defaultValue'] = (int)$argument->getDefault(); @@ -126,11 +114,7 @@ public function getRepresentation(Argument $argument) : array */ public function getFieldRepresentation(string $type) : InputType { - if ($this->scalarTypes->hasScalarTypeClass($type)) { - return $this->scalarTypes->getScalarTypeInstance($type); - } else { - $configElement = $this->config->getTypeStructure($type); - return $this->inputFactory->create($configElement); - } + $configElement = $this->config->getTypeStructure($type); + return $this->inputFactory->create($configElement); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php index a3b8f77190538..5e1eced223172 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php @@ -99,7 +99,6 @@ public function __construct( /** * {@inheritDoc} - * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function format(StructureInterface $typeStructure, OutputType $outputType) : array { @@ -112,7 +111,13 @@ public function format(StructureInterface $typeStructure, OutputType $outputType if ($typeStructure->getName() == $field->getType()) { $type = $outputType; } else { - $type = $this->getFieldType($typeStructure, $field, $outputType); + if ($typeStructure->getName() == $field->getType()) { + $type = $outputType; + } else { + $type = $this->outputMapper->getTypeObject($field->getType()); + } + + $type = $this->wrappedTypeProcessor->processWrappedType($field, $type); } } $config['fields'][$field->getName()] = [ @@ -138,27 +143,6 @@ function ($value, $args, $context, $info) use ($resolver, $field) { return $config; } - /** - * Determine field's type based on configured attributes. - * - * @param StructureInterface $typeStructure - * @param Field $field - * @param OutputType $outputType - * @return OutputType - */ - private function getFieldType(StructureInterface $typeStructure, Field $field, OutputType $outputType) : OutputType - { - if ($typeStructure->getName() == $field->getType()) { - $type = $outputType; - } else { - $type = $this->outputMapper->getTypeObject($field->getType()); - } - - $type = $this->wrappedTypeProcessor->processWrappedType($field, $type); - - return $type; - } - /** * Format arguments configured for passed in field. * From f40dc9ff9ac307c6cd6ad29ca2421314c8cc9298 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 13 Mar 2018 21:00:55 -0500 Subject: [PATCH 065/668] MAGETWO-89031: Make all graphql methods to return strict type - refactor --- .../Magento/Framework/GraphQl/Config/Data/Argument.php | 2 +- .../Magento/Framework/GraphQl/Config/Data/Field.php | 2 +- .../Framework/GraphQl/Config/Data/FieldInterface.php | 2 +- .../GraphQl/Config/Data/WrappedTypeProcessor.php | 6 +++--- lib/internal/Magento/Framework/GraphQl/SchemaProvider.php | 2 +- .../Framework/GraphQl/Type/Definition/ScalarTypes.php | 4 ++-- .../Magento/Framework/GraphQl/Type/Input/InputMapper.php | 8 ++++---- .../Framework/GraphQl/Type/Input/InputObjectType.php | 6 +++--- .../Type/Output/ElementMapper/Formatter/Fields.php | 8 ++++---- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php index c450c3fdf2919..8429c1ed068a5 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php @@ -99,7 +99,7 @@ public function getName() : string * * @return string */ - public function getType() : string + public function getTypeName() : string { return $this->type; } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php index 2c9f3a5f90617..26888a73a3bb7 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php @@ -88,7 +88,7 @@ public function getName() : string * * @return string */ - public function getType() : string + public function getTypeName() : string { return $this->type; } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/FieldInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/FieldInterface.php index c81f7539fc836..267b3345b28fb 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/FieldInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/FieldInterface.php @@ -17,7 +17,7 @@ interface FieldInterface extends StructureInterface * * @return string */ - public function getType() : string; + public function getTypeName() : string; /** * Return true if argument is a list of input items, otherwise false if it is a single object/scalar. diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/WrappedTypeProcessor.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/WrappedTypeProcessor.php index b68beec8bfda0..079a62aa39c83 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/WrappedTypeProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/WrappedTypeProcessor.php @@ -64,7 +64,7 @@ public function processScalarWrappedType( TypeInterface $object = null ) : \GraphQL\Type\Definition\Type { if (!$object) { - $object = $this->scalarTypes->getScalarTypeInstance($field->getType()); + $object = $this->scalarTypes->getScalarTypeInstance($field->getTypeName()); } return $this->processScalarIsNullable($field, $this->processScalarIsList($field, $object)); } @@ -115,7 +115,7 @@ private function processScalarIsNullable( FieldInterface $field, \GraphQL\Type\Definition\Type $object = null ) : \GraphQL\Type\Definition\Type { - $object = $object ?: $this->scalarTypes->getScalarTypeInstance($field->getType()); + $object = $object ?: $this->scalarTypes->getScalarTypeInstance($field->getTypeName()); if ($field->isRequired()) { return $this->scalarTypes->createNonNull($object); } @@ -133,7 +133,7 @@ private function processScalarIsList( FieldInterface $field, \GraphQL\Type\Definition\Type $object = null ) : \GraphQL\Type\Definition\Type { - $object = $object ?: $this->scalarTypes->getScalarTypeInstance($field->getType()); + $object = $object ?: $this->scalarTypes->getScalarTypeInstance($field->getTypeName()); if ($field->isList()) { if ($field instanceof \Magento\Framework\GraphQl\Config\Data\Argument) { if ($field->areItemsRequired()) { diff --git a/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php b/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php index 083e25e236684..bbb6ca1e1f3e5 100644 --- a/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php +++ b/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php @@ -57,7 +57,7 @@ public function getTypes() : array { $types = []; foreach ($this->config->getDeclaredTypeNames() as $typeName) { - if ($this->scalarTypes->hasScalarTypeClass($typeName)) { + if ($this->scalarTypes->hasScalarTypeName($typeName)) { $types[$typeName] = $this->scalarTypes->getScalarTypeInstance($typeName); } else { $types[$typeName] = $this->outputMapper->getTypeObject($typeName); diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php index dcc925f7db2c1..3b91feb58b287 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php @@ -16,7 +16,7 @@ class ScalarTypes * @param string $typeName * @return bool */ - public function hasScalarTypeClass(string $typeName) : bool + public function hasScalarTypeName(string $typeName) : bool { $internalTypes = \GraphQL\Type\Definition\Type::getInternalTypes(); return isset($internalTypes[$typeName]) ? true : false; @@ -30,7 +30,7 @@ public function hasScalarTypeClass(string $typeName) : bool public function getScalarTypeInstance(string $typeName) : \GraphQL\Type\Definition\Type { $internalTypes = \GraphQL\Type\Definition\Type::getInternalTypes(); - if ($this->hasScalarTypeClass($typeName)) { + if ($this->hasScalarTypeName($typeName)) { return $internalTypes[$typeName]; } else { throw new \LogicException(sprintf('Scalar type %s doesn\'t exist', $typeName)); diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php index 84b6ac28070f9..b9bc6f93e2d34 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php @@ -73,8 +73,8 @@ public function __construct( */ public function getRepresentation(Argument $argument) : array { - $type = $argument->getType(); - if ($this->scalarTypes->hasScalarTypeClass($type)) { + $type = $argument->getTypeName(); + if ($this->scalarTypes->hasScalarTypeName($type)) { $instance = $this->wrappedTypeProcessor->processScalarWrappedType($argument); } else { $configElement = $this->config->getTypeStructure($type); @@ -87,8 +87,8 @@ public function getRepresentation(Argument $argument) : array 'description' => $argument->getDescription() ]; - if (!$this->scalarTypes->hasScalarTypeClass($type) && $argument->getDefault() !== null) { - switch ($argument->getType()) { + if (!$this->scalarTypes->hasScalarTypeName($type) && $argument->getDefault() !== null) { + switch ($argument->getTypeName()) { case 'Int': $calculatedArgument['defaultValue'] = (int)$argument->getDefault(); break; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php index 8c09aff797354..dc65eb0b9a04b 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php @@ -57,13 +57,13 @@ public function __construct( 'description' => $structure->getDescription() ]; foreach ($structure->getFields() as $field) { - if ($this->scalarTypes->hasScalarTypeClass($field->getType())) { + if ($this->scalarTypes->hasScalarTypeName($field->getTypeName())) { $type = $type = $this->wrappedTypeProcessor->processScalarWrappedType($field); } else { - if ($field->getType() == $structure->getName()) { + if ($field->getTypeName() == $structure->getName()) { $type = $this; } else { - $type = $inputMapper->getFieldRepresentation($field->getType()); + $type = $inputMapper->getFieldRepresentation($field->getTypeName()); } $type = $this->wrappedTypeProcessor->processWrappedType($field, $type); } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php index 5e1eced223172..7ab18dc4bb31a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php @@ -105,16 +105,16 @@ public function format(StructureInterface $typeStructure, OutputType $outputType $config = []; /** @var Field $field */ foreach ($typeStructure->getFields() as $field) { - if ($this->scalarTypes->hasScalarTypeClass($field->getType())) { + if ($this->scalarTypes->hasScalarTypeName($field->getTypeName())) { $type = $this->wrappedTypeProcessor->processScalarWrappedType($field); } else { - if ($typeStructure->getName() == $field->getType()) { + if ($typeStructure->getName() == $field->getTypeName()) { $type = $outputType; } else { - if ($typeStructure->getName() == $field->getType()) { + if ($typeStructure->getName() == $field->getTypeName()) { $type = $outputType; } else { - $type = $this->outputMapper->getTypeObject($field->getType()); + $type = $this->outputMapper->getTypeObject($field->getTypeName()); } $type = $this->wrappedTypeProcessor->processWrappedType($field, $type); From 6b204ccd317bca688bdf4af2701ca0db20e5dc79 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 13 Mar 2018 22:57:51 -0500 Subject: [PATCH 066/668] MAGETWO-89031: Make all graphql methods to return strict type - refactor --- .../GraphQl/Config/Data/FieldInterface.php | 2 +- .../GraphQl/Config/Data/InterfaceType.php | 2 +- .../Config/Data/OutputFieldInterface.php | 2 +- .../Framework/GraphQl/Config/Data/Type.php | 2 +- .../GraphQl/Config/Data/TypeInterface.php | 21 +++++++++++++++ .../Config/Data/WrappedTypeProcessor.php | 2 +- .../Framework/GraphQl/SchemaProvider.php | 2 +- .../GraphQl/Type/Definition/ScalarTypes.php | 4 +-- .../GraphQl/Type/Input/InputMapper.php | 20 +++----------- .../GraphQl/Type/Input/InputObjectType.php | 26 +++++++++++++++---- .../Output/ElementMapper/Formatter/Fields.php | 7 +++-- .../ElementMapper/Formatter/Interfaces.php | 4 +-- .../ElementMapper/Formatter/ResolveType.php | 4 +-- .../ElementMapper/FormatterComposite.php | 4 +-- .../ElementMapper/FormatterInterface.php | 6 ++--- 15 files changed, 66 insertions(+), 42 deletions(-) create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Data/TypeInterface.php diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/FieldInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/FieldInterface.php index 267b3345b28fb..9d4d364d3fdb4 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/FieldInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/FieldInterface.php @@ -8,7 +8,7 @@ namespace Magento\Framework\GraphQl\Config\Data; /** - * Defines contracts for general fields data objects that, combined, represent a configured GraphQL schema. + * Defines contract for fields data as GraphQL objects. */ interface FieldInterface extends StructureInterface { diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/InterfaceType.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/InterfaceType.php index 8afa13ed794c4..6e72f9d631e84 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/InterfaceType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/InterfaceType.php @@ -10,7 +10,7 @@ /** * Describes the configured data for a GraphQL interface type. */ -class InterfaceType implements StructureInterface +class InterfaceType implements TypeInterface { /** * @var string diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/OutputFieldInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/OutputFieldInterface.php index 632495887afe3..8aebeecb75087 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/OutputFieldInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/OutputFieldInterface.php @@ -8,7 +8,7 @@ namespace Magento\Framework\GraphQl\Config\Data; /** - * Defines contracts for output fields data objects that, combined, represent a configured GraphQL schema. + * Defines contract for output fields data as GraphQL objects. */ interface OutputFieldInterface extends FieldInterface { diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Type.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Type.php index 274c489854b45..ade68c0dad39a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Type.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Type.php @@ -10,7 +10,7 @@ /** * Describes all the configured data of an Output or Input type in GraphQL. */ -class Type implements StructureInterface +class Type implements TypeInterface { /** * @var string diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/TypeInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/TypeInterface.php new file mode 100644 index 0000000000000..ebe6d80902612 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/TypeInterface.php @@ -0,0 +1,21 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Framework\GraphQl\Config\Data; + +/** + * Defines contracts for return type data as GraphQL objects. + */ +interface TypeInterface extends StructureInterface +{ + /** + * Get a list of fields that make up the possible return or input values of a type. + * + * @return Field[] + */ + public function getFields() : array; +} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/WrappedTypeProcessor.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/WrappedTypeProcessor.php index 079a62aa39c83..78ae96a8e5a14 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/WrappedTypeProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/WrappedTypeProcessor.php @@ -12,7 +12,7 @@ use Magento\Framework\GraphQl\Type\Definition\ScalarTypes; /** - * Factory for @see TypeInterface implementations + * Processor for wrapped types for both custom and scalar types */ class WrappedTypeProcessor { diff --git a/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php b/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php index bbb6ca1e1f3e5..4129716fbe034 100644 --- a/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php +++ b/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php @@ -57,7 +57,7 @@ public function getTypes() : array { $types = []; foreach ($this->config->getDeclaredTypeNames() as $typeName) { - if ($this->scalarTypes->hasScalarTypeName($typeName)) { + if ($this->scalarTypes->isScalarType($typeName)) { $types[$typeName] = $this->scalarTypes->getScalarTypeInstance($typeName); } else { $types[$typeName] = $this->outputMapper->getTypeObject($typeName); diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php index 3b91feb58b287..0f7256536d21e 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Definition/ScalarTypes.php @@ -16,7 +16,7 @@ class ScalarTypes * @param string $typeName * @return bool */ - public function hasScalarTypeName(string $typeName) : bool + public function isScalarType(string $typeName) : bool { $internalTypes = \GraphQL\Type\Definition\Type::getInternalTypes(); return isset($internalTypes[$typeName]) ? true : false; @@ -30,7 +30,7 @@ public function hasScalarTypeName(string $typeName) : bool public function getScalarTypeInstance(string $typeName) : \GraphQL\Type\Definition\Type { $internalTypes = \GraphQL\Type\Definition\Type::getInternalTypes(); - if ($this->hasScalarTypeName($typeName)) { + if ($this->isScalarType($typeName)) { return $internalTypes[$typeName]; } else { throw new \LogicException(sprintf('Scalar type %s doesn\'t exist', $typeName)); diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php index b9bc6f93e2d34..328dd22cc6983 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php @@ -73,11 +73,11 @@ public function __construct( */ public function getRepresentation(Argument $argument) : array { - $type = $argument->getTypeName(); - if ($this->scalarTypes->hasScalarTypeName($type)) { + $typeName = $argument->getTypeName(); + if ($this->scalarTypes->isScalarType($typeName)) { $instance = $this->wrappedTypeProcessor->processScalarWrappedType($argument); } else { - $configElement = $this->config->getTypeStructure($type); + $configElement = $this->config->getTypeStructure($typeName); $instance = $this->inputFactory->create($configElement); $instance = $this->wrappedTypeProcessor->processWrappedType($argument, $instance); } @@ -87,7 +87,7 @@ public function getRepresentation(Argument $argument) : array 'description' => $argument->getDescription() ]; - if (!$this->scalarTypes->hasScalarTypeName($type) && $argument->getDefault() !== null) { + if ($this->scalarTypes->isScalarType($typeName) && $argument->getDefault() !== null) { switch ($argument->getTypeName()) { case 'Int': $calculatedArgument['defaultValue'] = (int)$argument->getDefault(); @@ -105,16 +105,4 @@ public function getRepresentation(Argument $argument) : array return $calculatedArgument; } - - /** - * Return object representation of field for passed in type. - * - * @param string $type - * @return InputType - */ - public function getFieldRepresentation(string $type) : InputType - { - $configElement = $this->config->getTypeStructure($type); - return $this->inputFactory->create($configElement); - } } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php index dc65eb0b9a04b..6b655fca7c113 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php @@ -14,6 +14,7 @@ use Magento\Framework\GraphQl\TypeFactory; use Magento\Framework\GraphQl\Type\Definition\ScalarTypes; use Magento\Framework\GraphQl\Config\Data\WrappedTypeProcessor; +use Magento\Framework\GraphQl\Config\ConfigInterface; /** * Class InputObjectType @@ -36,34 +37,49 @@ class InputObjectType extends \Magento\Framework\GraphQl\Type\Definition\InputOb private $wrappedTypeProcessor; /** - * @param InputMapper $inputMapper + * @var InputFactory + */ + private $inputFactory; + + /** + * @var ConfigInterface + */ + public $graphQlConfig; + + /** * @param TypeStructure $structure * @param TypeFactory $typeFactory * @param ScalarTypes $scalarTypes * @param WrappedTypeProcessor $wrappedTypeProcessor + * @param InputFactory $inputFactory + * @param ConfigInterface $graphQlConfig */ public function __construct( - InputMapper $inputMapper, TypeStructure $structure, TypeFactory $typeFactory, ScalarTypes $scalarTypes, - WrappedTypeProcessor $wrappedTypeProcessor + WrappedTypeProcessor $wrappedTypeProcessor, + InputFactory $inputFactory, + ConfigInterface $graphQlConfig ) { $this->typeFactory = $typeFactory; $this->scalarTypes = $scalarTypes; $this->wrappedTypeProcessor = $wrappedTypeProcessor; + $this->inputFactory = $inputFactory; + $this->graphQlConfig = $graphQlConfig; $config = [ 'name' => $structure->getName(), 'description' => $structure->getDescription() ]; foreach ($structure->getFields() as $field) { - if ($this->scalarTypes->hasScalarTypeName($field->getTypeName())) { + if ($this->scalarTypes->isScalarType($field->getTypeName())) { $type = $type = $this->wrappedTypeProcessor->processScalarWrappedType($field); } else { if ($field->getTypeName() == $structure->getName()) { $type = $this; } else { - $type = $inputMapper->getFieldRepresentation($field->getTypeName()); + $configElement = $this->graphQlConfig->getTypeStructure($field->getTypeName()); + $type = $this->inputFactory->create($configElement); } $type = $this->wrappedTypeProcessor->processWrappedType($field, $type); } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php index 7ab18dc4bb31a..d372b79d452d3 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php @@ -9,14 +9,13 @@ use Magento\Framework\GraphQl\Type\Definition\OutputType; use Magento\Framework\GraphQl\ArgumentFactory; -use Magento\Framework\GraphQl\Config\Data\StructureInterface; +use Magento\Framework\GraphQl\Config\Data\TypeInterface; use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\Framework\GraphQl\Type\Input\InputMapper; use Magento\Framework\GraphQl\Type\Output\ElementMapper\FormatterInterface; use Magento\Framework\GraphQl\Type\Output\OutputMapper; use Magento\Framework\GraphQl\TypeFactory; use Magento\Framework\GraphQl\Config\Data\Field; -use Magento\Framework\GraphQl\Type\Definition\TypeInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\GraphQl\Config\FieldConfig; use Magento\Framework\GraphQl\Type\Definition\ScalarTypes; @@ -100,12 +99,12 @@ public function __construct( /** * {@inheritDoc} */ - public function format(StructureInterface $typeStructure, OutputType $outputType) : array + public function format(TypeInterface $typeStructure, OutputType $outputType) : array { $config = []; /** @var Field $field */ foreach ($typeStructure->getFields() as $field) { - if ($this->scalarTypes->hasScalarTypeName($field->getTypeName())) { + if ($this->scalarTypes->isScalarType($field->getTypeName())) { $type = $this->wrappedTypeProcessor->processScalarWrappedType($field); } else { if ($typeStructure->getName() == $field->getTypeName()) { diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php index 9da0d2e9fac4f..cbb4d74efb231 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php @@ -8,7 +8,7 @@ namespace Magento\Framework\GraphQl\Type\Output\ElementMapper\Formatter; use Magento\Framework\GraphQl\Type\Definition\OutputType; -use Magento\Framework\GraphQl\Config\Data\StructureInterface; +use Magento\Framework\GraphQl\Config\Data\TypeInterface; use Magento\Framework\GraphQl\Config\Data\Type; use Magento\Framework\GraphQl\Type\Output\ElementMapper\FormatterInterface; use Magento\Framework\ObjectManagerInterface; @@ -41,7 +41,7 @@ public function __construct(ObjectManagerInterface $objectManager, OutputMapper /** * {@inheritDoc} */ - public function format(StructureInterface $typeStructure, OutputType $outputType) : array + public function format(TypeInterface $typeStructure, OutputType $outputType) : array { $config = []; if ($typeStructure instanceof Type && !empty($typeStructure->getInterfaces())) { diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/ResolveType.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/ResolveType.php index 853444dd920b9..03772ed6a2a14 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/ResolveType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/ResolveType.php @@ -8,7 +8,7 @@ namespace Magento\Framework\GraphQl\Type\Output\ElementMapper\Formatter; use Magento\Framework\GraphQl\Type\Definition\OutputType; -use Magento\Framework\GraphQl\Config\Data\StructureInterface; +use Magento\Framework\GraphQl\Config\Data\TypeInterface; use Magento\Framework\GraphQl\Type\Output\ElementMapper\FormatterInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\GraphQl\Config\Data\InterfaceType; @@ -34,7 +34,7 @@ public function __construct(ObjectManagerInterface $objectManager) /** * {@inheritDoc} */ - public function format(StructureInterface $typeStructure, OutputType $outputType) : array + public function format(TypeInterface $typeStructure, OutputType $outputType) : array { $config = []; if ($typeStructure instanceof InterfaceType) { diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterComposite.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterComposite.php index 4c1810868d458..69f1c84776824 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterComposite.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterComposite.php @@ -8,7 +8,7 @@ namespace Magento\Framework\GraphQl\Type\Output\ElementMapper; use Magento\Framework\GraphQl\Type\Definition\OutputType; -use Magento\Framework\GraphQl\Config\Data\StructureInterface; +use Magento\Framework\GraphQl\Config\Data\TypeInterface; /** * {@inheritdoc} @@ -31,7 +31,7 @@ public function __construct(array $formatters) /** * {@inheritDoc} */ - public function format(StructureInterface $typeStructure, OutputType $outputType) : array + public function format(TypeInterface $typeStructure, OutputType $outputType) : array { $config = [ 'name' => $typeStructure->getName(), diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterInterface.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterInterface.php index df71b875b4952..a8340719ceb23 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/FormatterInterface.php @@ -7,7 +7,7 @@ namespace Magento\Framework\GraphQl\Type\Output\ElementMapper; -use Magento\Framework\GraphQl\Config\Data\StructureInterface; +use Magento\Framework\GraphQl\Config\Data\TypeInterface; use Magento\Framework\GraphQl\Type\Definition\OutputType; /** @@ -18,9 +18,9 @@ interface FormatterInterface /** * Format specific type structure elements to GraphQL-readable array. * - * @param StructureInterface $typeStructure + * @param TypeInterface $typeStructure * @param OutputType $outputType * @return array */ - public function format(StructureInterface $typeStructure, OutputType $outputType) : array; + public function format(TypeInterface $typeStructure, OutputType $outputType) : array; } From b12bcb73bf849508ff8f6a4418fe1f6e66584a74 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 14 Mar 2018 10:52:27 -0500 Subject: [PATCH 067/668] MAGETWO-89091: CE edition - Update composer dependencies --- composer.json | 11 +++++-- composer.lock | 91 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 88 insertions(+), 14 deletions(-) diff --git a/composer.json b/composer.json index 95c1be27e7a99..f4bf0e9cd2376 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,12 @@ "preferred-install": "dist", "sort-packages": true }, + "repositories": { + "zf1": { + "type": "vcs", + "url": "https://github.com/magento-engcom/zf1-php-7.2-support.git" + } + }, "require": { "php": "~7.1.3||~7.2.0", "ext-ctype": "*", @@ -37,7 +43,7 @@ "composer/composer": "~1.6.0", "magento/composer": "1.3.0.x-dev", "magento/magento-composer-installer": ">=0.1.11", - "magento/zendframework1": "~1.13.0", + "magento/zendframework1": "dev-deprecated-7.2-code as 1.14.0", "monolog/monolog": "^1.17", "oyejorge/less.php": "~1.7.0", "pelago/emogrifier": "^2.0.0", @@ -75,7 +81,8 @@ "zendframework/zend-text": "^2.6.0", "zendframework/zend-uri": "^2.5.1", "zendframework/zend-validator": "^2.6.0", - "zendframework/zend-view": "^2.8.1" + "zendframework/zend-view": "^2.8.1", + "phpseclib/mcrypt_compat": "1.0.4" }, "require-dev": { "friendsofphp/php-cs-fixer": "~2.10.0", diff --git a/composer.lock b/composer.lock index c5b034983773a..f40d49ed7b1d0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "515dea17aa476ce86a88aa67eb2e3263", - "content-hash": "17e237a86feb252b106b651946bd898f", + "hash": "ab176287e06df4501eabb23d308959cb", + "content-hash": "fc4d6d51bf1d69473aab77b19380d74e", "packages": [ { "name": "braintree/braintree_php", @@ -672,18 +672,25 @@ }, { "name": "magento/zendframework1", - "version": "1.13.1", + "version": "dev-deprecated-7.2-code", "source": { "type": "git", - "url": "https://github.com/magento/zf1.git", - "reference": "e2693f047bb7ccb8affa8f72ea40269f4c9f4fbf" + "url": "https://github.com/magento-engcom/zf1-php-7.2-support.git", + "reference": "1366f3fcca399f80c4b3195b8a0707ee460821c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/zf1/zipball/e2693f047bb7ccb8affa8f72ea40269f4c9f4fbf", - "reference": "e2693f047bb7ccb8affa8f72ea40269f4c9f4fbf", + "url": "https://api.github.com/repos/magento-engcom/zf1-php-7.2-support/zipball/1366f3fcca399f80c4b3195b8a0707ee460821c7", + "reference": "1366f3fcca399f80c4b3195b8a0707ee460821c7", "shasum": "" }, + "archive": { + "exclude": [ + "/demos", + "/documentation", + "/tests" + ] + }, "require": { "php": ">=5.2.11" }, @@ -702,7 +709,6 @@ "Zend_": "library/" } }, - "notification-url": "https://packagist.org/downloads/", "include-path": [ "library/" ], @@ -712,10 +718,14 @@ "description": "Magento Zend Framework 1", "homepage": "http://framework.zend.com/", "keywords": [ - "ZF1", - "framework" + "framework", + "zf1" ], - "time": "2017-06-21 14:56:23" + "support": { + "source": "https://github.com/magento-engcom/zf1-php-7.2-support/tree/deprecated-7.2-code", + "issues": "https://github.com/magento-engcom/zf1-php-7.2-support/issues" + }, + "time": "2018-03-12 19:46:30" }, { "name": "monolog/monolog", @@ -1028,6 +1038,55 @@ ], "time": "2015-08-11 12:30:09" }, + { + "name": "phpseclib/mcrypt_compat", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/mcrypt_compat.git", + "reference": "034ee0e920c70b589196d0bb0a7e8babae5fce08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/mcrypt_compat/zipball/034ee0e920c70b589196d0bb0a7e8babae5fce08", + "reference": "034ee0e920c70b589196d0bb0a7e8babae5fce08", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpseclib/phpseclib": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35|^5.7|^6.0" + }, + "suggest": { + "ext-openssl": "Will enable faster cryptographic operations" + }, + "type": "library", + "autoload": { + "files": [ + "lib/mcrypt.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "homepage": "http://phpseclib.sourceforge.net" + } + ], + "description": "PHP 7.1 polyfill for the mcrypt extension from PHP <= 7.0", + "keywords": [ + "cryptograpy", + "encryption", + "mcrypt" + ], + "time": "2018-01-13 23:07:52" + }, { "name": "phpseclib/phpseclib", "version": "2.0.10", @@ -6247,10 +6306,18 @@ "time": "2018-01-29 19:49:41" } ], - "aliases": [], + "aliases": [ + { + "alias": "1.14.0", + "alias_normalized": "1.14.0.0", + "version": "dev-deprecated-7.2-code", + "package": "magento/zendframework1" + } + ], "minimum-stability": "stable", "stability-flags": { "magento/composer": 20, + "magento/zendframework1": 20, "phpmd/phpmd": 0 }, "prefer-stable": true, From a039950f6487f010a334cf6f395384fa7a4df95f Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 14 Mar 2018 11:14:51 -0500 Subject: [PATCH 068/668] MAGETWO-89091: CE edition - Update composer dependencies - fix unit test failures --- .../Magento/Backend/Block/Widget/Grid/ColumnSet.php | 3 ++- app/code/Magento/Bundle/Model/Product/Type.php | 7 ++++--- .../Model/Layer/Filter/DataProvider/Decimal.php | 4 ++-- .../Catalog/Model/ResourceModel/AbstractResource.php | 2 +- .../Test/Unit/Model/ResourceModel/AbstractTest.php | 2 +- .../Model/ProductScopeRewriteGenerator.php | 2 +- .../Test/Unit/Model/Import/SourceAbstractTest.php | 2 +- .../Observer/Backend/CustomerQuoteObserverTest.php | 4 ++-- app/code/Magento/Swatches/Helper/Data.php | 2 +- app/code/Magento/Weee/Model/Tax.php | 2 +- .../Test/Unit/Code/Generator/_files/SampleMapper.txt | 4 ++-- .../code/Magento/SomeModule/Model/SevenInterface.php | 2 +- .../Magento/Framework/Data/Collection/AbstractDb.php | 3 ++- .../Framework/Encryption/Test/Unit/CryptTest.php | 8 ++++---- .../Framework/Interception/PluginList/PluginList.php | 2 +- .../Framework/Mail/Test/Unit/TransportTest.php | 2 +- .../Test/Unit/Code/Generator/_files/SampleFactory.txt | 2 +- .../Unit/Code/Generator/_files/SampleRepository.txt | 4 ++-- .../Unit/Code/Generator/_files/TSampleRepository.txt | 4 ++-- .../Magento/Framework/Session/SessionManager.php | 11 ++++++++--- .../Unit/Layout/Argument/Interpreter/OptionsTest.php | 5 ++++- .../src/Magento/Setup/Console/Style/MagentoStyle.php | 8 ++++---- 22 files changed, 48 insertions(+), 37 deletions(-) diff --git a/app/code/Magento/Backend/Block/Widget/Grid/ColumnSet.php b/app/code/Magento/Backend/Block/Widget/Grid/ColumnSet.php index 1a6f937f1171d..9443ffefbc0df 100644 --- a/app/code/Magento/Backend/Block/Widget/Grid/ColumnSet.php +++ b/app/code/Magento/Backend/Block/Widget/Grid/ColumnSet.php @@ -258,7 +258,8 @@ public function getRowUrl($item) */ public function getMultipleRows($item) { - return $item->getChildren(); + $children = $item->getChildren(); + return $children ?: []; } /** diff --git a/app/code/Magento/Bundle/Model/Product/Type.php b/app/code/Magento/Bundle/Model/Product/Type.php index b4071096992c1..dad350a82ebaf 100644 --- a/app/code/Magento/Bundle/Model/Product/Type.php +++ b/app/code/Magento/Bundle/Model/Product/Type.php @@ -706,7 +706,7 @@ protected function _prepareProduct(\Magento\Framework\DataObject $buyRequest, $p $selections = $this->mergeSelectionsWithOptions($options, $selections); } - if (count($selections) > 0 || !$isStrictProcessMode) { + if ((is_array($selections) && count($selections) > 0) || !$isStrictProcessMode) { $uniqueKey = [$product->getId()]; $selectionIds = []; $qtys = $buyRequest->getBundleOptionQty(); @@ -1322,8 +1322,9 @@ protected function checkIsResult($_result) protected function mergeSelectionsWithOptions($options, $selections) { foreach ($options as $option) { - if ($option->getRequired() && count($option->getSelections()) == 1) { - $selections = array_merge($selections, $option->getSelections()); + $optionSelections = $option->getSelections(); + if ($option->getRequired() && is_array($optionSelections) && count($optionSelections) == 1) { + $selections = array_merge($selections, $optionSelections); } else { $selections = []; break; diff --git a/app/code/Magento/Catalog/Model/Layer/Filter/DataProvider/Decimal.php b/app/code/Magento/Catalog/Model/Layer/Filter/DataProvider/Decimal.php index 36caa148b2e4e..bb1fce309f4f4 100644 --- a/app/code/Magento/Catalog/Model/Layer/Filter/DataProvider/Decimal.php +++ b/app/code/Magento/Catalog/Model/Layer/Filter/DataProvider/Decimal.php @@ -56,7 +56,7 @@ public function getRange(FilterInterface $filter) $index = 1; do { $range = pow(10, strlen(floor($maxValue)) - $index); - $items = $this->getRangeItemCounts($range, $filter); + $items = $this->getRangeItemCounts($range, $filter) ?: []; $index++; } while ($range > self::MIN_RANGE_POWER && count($items) < 2); $this->range = $range; @@ -109,7 +109,7 @@ public function getMinValue(FilterInterface $filter) * * @param int $range * @param FilterInterface $filter - * @return mixed + * @return array */ public function getRangeItemCounts($range, FilterInterface $filter) { diff --git a/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php b/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php index 2e5b4ca538ffe..b9e629912a5b3 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php @@ -78,7 +78,7 @@ public function getDefaultStoreId() */ protected function _isApplicableAttribute($object, $attribute) { - $applyTo = $attribute->getApplyTo(); + $applyTo = $attribute->getApplyTo() ?: []; return (count($applyTo) == 0 || in_array($object->getTypeId(), $applyTo)) && $attribute->isInSet($object->getAttributeSetId()); } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/AbstractTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/AbstractTest.php index 96336d2b0706a..3dcea33d5e00e 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/AbstractTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/AbstractTest.php @@ -25,7 +25,7 @@ protected function _getAttributes() foreach ($codes as $code) { $mock = $this->createPartialMock( \Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class, - ['isInSet', 'getBackend', '__wakeup'] + ['isInSet', 'getApplyTo', 'getBackend', '__wakeup'] ); $mock->setAttributeId($code); diff --git a/app/code/Magento/CatalogUrlRewrite/Model/ProductScopeRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/ProductScopeRewriteGenerator.php index 9c5c37b51f0b2..6b838f83d31e4 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/ProductScopeRewriteGenerator.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/ProductScopeRewriteGenerator.php @@ -208,7 +208,7 @@ public function generateForSpecificStoreView($storeId, $productCategories, Produ public function isCategoryProperForGenerating(Category $category, $storeId) { $parentIds = $category->getParentIds(); - if (count($parentIds) >= 2) { + if (is_array($parentIds) && count($parentIds) >= 2) { $rootCategoryId = $parentIds[1]; return $rootCategoryId == $this->storeManager->getStore($storeId)->getRootCategoryId(); } diff --git a/app/code/Magento/ImportExport/Test/Unit/Model/Import/SourceAbstractTest.php b/app/code/Magento/ImportExport/Test/Unit/Model/Import/SourceAbstractTest.php index 06d2292dfb1a0..ba65677d53b95 100644 --- a/app/code/Magento/ImportExport/Test/Unit/Model/Import/SourceAbstractTest.php +++ b/app/code/Magento/ImportExport/Test/Unit/Model/Import/SourceAbstractTest.php @@ -57,7 +57,7 @@ public function testIteratorInterface() )->method( '_getNextRow' )->will( - $this->onConsecutiveCalls([1, 2, 3], [4, 5, 5], [6, 7, 8]) + $this->onConsecutiveCalls([1, 2, 3], [4, 5, 5], [6, 7, 8], []) ); $data = []; foreach ($this->_model as $key => $value) { diff --git a/app/code/Magento/Quote/Test/Unit/Observer/Backend/CustomerQuoteObserverTest.php b/app/code/Magento/Quote/Test/Unit/Observer/Backend/CustomerQuoteObserverTest.php index 682045c0cdb25..b82d1fa6c7839 100644 --- a/app/code/Magento/Quote/Test/Unit/Observer/Backend/CustomerQuoteObserverTest.php +++ b/app/code/Magento/Quote/Test/Unit/Observer/Backend/CustomerQuoteObserverTest.php @@ -160,8 +160,8 @@ public function testDispatch($isWebsiteScope, $websites) public function dispatchDataProvider() { return [ - [true, ['website1']], - [true, ['website1', 'website2']], + [true, [['website1']]], + [true, [['website1'], ['website2']]], [false, ['website1']], [false, ['website1', 'website2']], ]; diff --git a/app/code/Magento/Swatches/Helper/Data.php b/app/code/Magento/Swatches/Helper/Data.php index 7696585293546..81d92f8b915ba 100644 --- a/app/code/Magento/Swatches/Helper/Data.php +++ b/app/code/Magento/Swatches/Helper/Data.php @@ -515,7 +515,7 @@ private function addFallbackOptions(array $fallbackValues, array $swatches) */ public function isProductHasSwatch(Product $product) { - $swatchAttributes = $this->getSwatchAttributes($product); + $swatchAttributes = $this->getSwatchAttributes($product) ?: []; return count($swatchAttributes) > 0; } diff --git a/app/code/Magento/Weee/Model/Tax.php b/app/code/Magento/Weee/Model/Tax.php index ae370b41ec192..3c6d29ae75217 100644 --- a/app/code/Magento/Weee/Model/Tax.php +++ b/app/code/Magento/Weee/Model/Tax.php @@ -326,7 +326,7 @@ public function getProductWeeeAttributes( $amountExclTax = $amountInclTax - $taxAmount; } else { $appliedRates = $this->_calculationFactory->create()->getAppliedRates($rateRequest); - if (count($appliedRates) > 1) { + if (is_array($appliedRates) && count($appliedRates) > 1) { $taxAmount = 0; foreach ($appliedRates as $appliedRate) { $taxRate = $appliedRate['percent']; diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleMapper.txt b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleMapper.txt index 21b81bad090e5..ec0397dac9e2d 100644 --- a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleMapper.txt +++ b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleMapper.txt @@ -17,9 +17,9 @@ class SampleMapper * * @var array */ - protected $registry = array( + protected $registry = [ - ); + ]; /** * Mapper constructor diff --git a/lib/internal/Magento/Framework/Code/Test/Unit/_files/app/code/Magento/SomeModule/Model/SevenInterface.php b/lib/internal/Magento/Framework/Code/Test/Unit/_files/app/code/Magento/SomeModule/Model/SevenInterface.php index d2539c9b73153..66c74bbf04e6f 100644 --- a/lib/internal/Magento/Framework/Code/Test/Unit/_files/app/code/Magento/SomeModule/Model/SevenInterface.php +++ b/lib/internal/Magento/Framework/Code/Test/Unit/_files/app/code/Magento/SomeModule/Model/SevenInterface.php @@ -32,7 +32,7 @@ interface SevenInterface extends \Magento\Framework\Code\Generator\CodeGenerator * @param array $data * @return TestThree */ - public static function testMethod1(array &$data = array()); + public static function testMethod1(array &$data = []); /** * Method short description diff --git a/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php b/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php index a36a97d0be7f1..4feaf21d2b2e8 100644 --- a/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php +++ b/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php @@ -237,7 +237,8 @@ public function getSelectCountSql() $countSelect->reset(\Magento\Framework\DB\Select::LIMIT_OFFSET); $countSelect->reset(\Magento\Framework\DB\Select::COLUMNS); - if (!count($this->getSelect()->getPart(\Magento\Framework\DB\Select::GROUP))) { + $part = $this->getSelect()->getPart(\Magento\Framework\DB\Select::GROUP); + if (!is_array($part) || !count($part)) { $countSelect->columns(new \Zend_Db_Expr('COUNT(*)')); return $countSelect; } diff --git a/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php b/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php index 6dc0d4a1d4628..55a078aaade7d 100644 --- a/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php +++ b/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php @@ -81,7 +81,7 @@ public function getCipherModeCombinations() $result = []; foreach ($this->_supportedCiphers as $cipher) { foreach ($this->_supportedModes as $mode) { - $result[] = [$cipher, $mode]; + $result[$cipher . '-' . $mode] = [$cipher, $mode]; } } return $result; @@ -110,9 +110,9 @@ public function getConstructorExceptionData() $tooLongKey = str_repeat('-', $this->_getKeySize($cipher, $mode) + 1); $tooShortInitVector = str_repeat('-', $this->_getInitVectorSize($cipher, $mode) - 1); $tooLongInitVector = str_repeat('-', $this->_getInitVectorSize($cipher, $mode) + 1); - $result[] = [$tooLongKey, $cipher, $mode, false]; - $result[] = [$this->_key, $cipher, $mode, $tooShortInitVector]; - $result[] = [$this->_key, $cipher, $mode, $tooLongInitVector]; + $result['tooLongKey-' . $cipher . '-' . $mode . '-false'] = [$tooLongKey, $cipher, $mode, false]; + $result['key-' . $cipher . '-' . $mode . '-tooShortInitVector'] = [$this->_key, $cipher, $mode, $tooShortInitVector]; + $result['key-' . $cipher . '-' . $mode . '-tooLongInitVector'] = [$this->_key, $cipher, $mode, $tooLongInitVector]; } } return $result; diff --git a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php index 489755a2846fc..82738a30266d8 100644 --- a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php +++ b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php @@ -295,7 +295,7 @@ protected function _loadScopedData() $virtualTypes = []; foreach ($this->_scopePriorityScheme as $scopeCode) { if (false == isset($this->_loadedScopes[$scopeCode])) { - $data = $this->_reader->read($scopeCode); + $data = $this->_reader->read($scopeCode) ?: []; unset($data['preferences']); if (count($data) > 0) { $this->_inherited = []; diff --git a/lib/internal/Magento/Framework/Mail/Test/Unit/TransportTest.php b/lib/internal/Magento/Framework/Mail/Test/Unit/TransportTest.php index 12889d9af8fd7..3cbe6fc923cdd 100644 --- a/lib/internal/Magento/Framework/Mail/Test/Unit/TransportTest.php +++ b/lib/internal/Magento/Framework/Mail/Test/Unit/TransportTest.php @@ -10,7 +10,7 @@ class TransportTest extends \PHPUnit\Framework\TestCase /** * @covers \Magento\Framework\Mail\Transport::sendMessage * @expectedException \Magento\Framework\Exception\MailException - * @expectedExceptionMessage Invalid email; contains no "To" header + * @expectedExceptionMessage Invalid email; contains no at least one of "To", "Cc", and "Bcc" header */ public function testSendMessageBrokenMessage() { diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleFactory.txt b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleFactory.txt index 37960239cb2c3..ad78440c5c9f2 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleFactory.txt +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleFactory.txt @@ -37,7 +37,7 @@ class SampleFactory * @param array $data * @return \Magento\Framework\ObjectManager\Code\Generator\Sample */ - public function create(array $data = array()) + public function create(array $data = []) { return $this->_objectManager->create($this->_instanceName, $data); } diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt index 5cc2e35598b89..7c5fc6f97eef1 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt @@ -27,9 +27,9 @@ class SampleRepository implements SampleRepositoryInterface * * @var array */ - protected $registry = array( + protected $registry = [ - ); + ]; /** * Extension attributes join processor. diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/TSampleRepository.txt b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/TSampleRepository.txt index bb2da3499c14d..10315080aefac 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/TSampleRepository.txt +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/TSampleRepository.txt @@ -27,9 +27,9 @@ class TSampleRepository implements TSampleRepositoryInterface * * @var array */ - protected $registry = array( + protected $registry = [ - ); + ]; /** * Extension attributes join processor. diff --git a/lib/internal/Magento/Framework/Session/SessionManager.php b/lib/internal/Magento/Framework/Session/SessionManager.php index cfabff6955e49..59990441aa8ae 100644 --- a/lib/internal/Magento/Framework/Session/SessionManager.php +++ b/lib/internal/Magento/Framework/Session/SessionManager.php @@ -124,9 +124,6 @@ public function __construct( $this->cookieManager = $cookieManager; $this->cookieMetadataFactory = $cookieMetadataFactory; $this->appState = $appState; - - // Enable session.use_only_cookies - ini_set('session.use_only_cookies', '1'); $this->start(); } @@ -576,6 +573,14 @@ public function expireSessionCookie() */ private function initIniOptions() { + $result = ini_set('session.use_only_cookies', '1'); + if ($result === false) { + $error = error_get_last(); + throw new \InvalidArgumentException( + sprintf('Failed to set ini option session.use_only_cookies to value 1. %s', $error['message']) + ); + } + foreach ($this->sessionConfig->getOptions() as $option => $value) { $result = ini_set($option, $value); if ($result === false) { diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Argument/Interpreter/OptionsTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Argument/Interpreter/OptionsTest.php index ffb79790d33f8..bf01355dcb491 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Argument/Interpreter/OptionsTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Argument/Interpreter/OptionsTest.php @@ -67,7 +67,10 @@ public function testEvaluate() */ public function testEvaluateWrongModel($input, $expectedException, $expectedExceptionMessage) { - $this->expectException($expectedException, $expectedExceptionMessage); + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + $this->_objectManager->method('get') + ->willReturnSelf(); $this->_model->evaluate($input); } diff --git a/setup/src/Magento/Setup/Console/Style/MagentoStyle.php b/setup/src/Magento/Setup/Console/Style/MagentoStyle.php index 4dec01f9497e1..c3f292ce76e1e 100755 --- a/setup/src/Magento/Setup/Console/Style/MagentoStyle.php +++ b/setup/src/Magento/Setup/Console/Style/MagentoStyle.php @@ -7,7 +7,6 @@ namespace Magento\Setup\Console\Style; use Magento\Setup\Console\InputValidationException; -use Symfony\Component\Console\Application; use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Helper\Helper; @@ -21,6 +20,7 @@ use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Style\OutputStyle; +use Symfony\Component\Console\Terminal; /** * Magento console output decorator. @@ -483,10 +483,10 @@ private function getProgressBar() */ private function getTerminalWidth() { - $application = new Application(); - $dimensions = $application->getTerminalDimensions(); + $terminal = new Terminal(); + $width = $terminal->getWidth(); - return $dimensions[0] ?: self::MAX_LINE_LENGTH; + return $width ?: self::MAX_LINE_LENGTH; } /** From 32a5f633c0914a17d5dd15abd8d45d0831e68599 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <okopylova@magento.com> Date: Wed, 14 Mar 2018 13:03:08 -0500 Subject: [PATCH 069/668] MAGETWO-89235: Update zend-view, zend-mvc and credis libs in EE - limit zendframework/zend-view dependency to fixed minor version --- composer.json | 2 +- composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 863c0a25c0bd6..c09f679cadaf2 100644 --- a/composer.json +++ b/composer.json @@ -76,7 +76,7 @@ "zendframework/zend-text": "^2.6.0", "zendframework/zend-uri": "^2.5.1", "zendframework/zend-validator": "^2.6.0", - "zendframework/zend-view": "^2.10.0" + "zendframework/zend-view": "~2.10.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "~2.1.1", diff --git a/composer.lock b/composer.lock index 0496603ccb707..40a27c656d000 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "b1c20b199edd4d000534ce72b84a5edf", + "content-hash": "13dfea4160f301d205183f0d920bbaf0", "packages": [ { "name": "braintree/braintree_php", From f0f87f66b93f38ab6b22d2579ae9e4d1c71b100b Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Wed, 14 Mar 2018 20:15:14 +0200 Subject: [PATCH 070/668] MAGETWO-87041: Product Filtering by additional price fields --- .../FilterProcessor/ProductPriceFilter.php | 42 +++++++++ .../Products/DataProvider/Product.php | 13 --- .../DataProvider/Product/Formatter/Price.php | 6 ++ .../Products/FilterArgument/AstConverter.php | 13 ++- .../Magento/CatalogGraphQl/etc/graphql.xml | 2 + .../Magento/CatalogGraphQl/etc/graphql/di.xml | 9 ++ .../GraphQl/Catalog/ProductViewTest.php | 88 ++++++++++++++++++- .../Magento/Catalog/_files/products_list.php | 66 ++++++++++++++ .../Catalog/_files/products_list_rollback.php | 41 +++++++++ 9 files changed, 264 insertions(+), 16 deletions(-) create mode 100644 app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductPriceFilter.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/products_list.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/products_list_rollback.php diff --git a/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductPriceFilter.php b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductPriceFilter.php new file mode 100644 index 0000000000000..a374ebe64e54a --- /dev/null +++ b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductPriceFilter.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Catalog\Model\ResourceModel\Product\Collection; +use Magento\Framework\Api\Filter; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +/** + * This filter is using indexers for prices and will not work without indexers + */ +class ProductPriceFilter implements CustomFilterInterface +{ + /** + * Apply prices Filter to Product Collection + * + * @param Filter $filter + * @param Collection $collection + * @return bool Whether the filter is applied + */ + public function apply(Filter $filter, AbstractDb $collection) : bool + { + $collection->addFinalPrice(); + $collection->addMinimalPrice(); + $collection->addPriceData(); + $collection->addTaxPercents(); + + $conditionType = $filter->getConditionType(); + $sqlCondition = $collection + ->getConnection() + ->prepareSqlCondition( + Collection::INDEX_TABLE_ALIAS . '.' . $filter->getField(), + [$conditionType => $filter->getValue()] + ); + $collection->getSelect()->where($sqlCondition); + return true; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php index 7604a4f4acfc2..b79d3c926dcdd 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php @@ -6,19 +6,12 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider; -use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Catalog\Model\Product\Option; -use Magento\Catalog\Model\Product\TierPrice; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\Data\SearchResultInterface; -use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\Serialize\SerializerInterface; -use Magento\Framework\Webapi\ServiceOutputProcessor; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Catalog\Api\Data\ProductSearchResultsInterfaceFactory; -use Magento\GraphQl\Model\EntityAttributeList; /** * Product field data provider, used for GraphQL resolver processing. @@ -82,21 +75,15 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr $this->collectionProcessor->process($searchCriteria, $collection); $collection->load(); - $collection->addCategoryIds(); - $collection->addFinalPrice(); $collection->addMediaGalleryData(); - $collection->addMinimalPrice(); - $collection->addPriceData(); $collection->addWebsiteNamesToResult(); $collection->addOptionsToResult(); - $collection->addTaxPercents(); $collection->addWebsiteNamesToResult(); $searchResult = $this->searchResultsFactory->create(); $searchResult->setSearchCriteria($searchCriteria); $searchResult->setItems($collection->getItems()); $searchResult->setTotalCount($collection->getSize()); - return $searchResult; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Price.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Price.php index 6de041a5631c2..892a880be2139 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Price.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Price.php @@ -45,6 +45,12 @@ public function __construct( */ public function format(Product $product, array $productData = []) { + /** + * This is workaround, because indexers do not work with catalogules, + * and after filtering price will be incorrect, so we need to load it with catalogules one + * more time + */ + $product->unsetData('minimal_price'); $priceInfo = $this->priceInfoFactory->create($product); /** @var \Magento\Catalog\Pricing\Price\FinalPriceInterface $finalPrice */ $finalPrice = $priceInfo->getPrice(FinalPrice::PRICE_CODE); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php index bcc8db4b69d6c..868a95b491c88 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php @@ -45,6 +45,10 @@ class AstConverter implements AstConverterInterface * @var ConfigInterface */ private $config; + /** + * @var array + */ + private $additionalAttributes; /** * @param ClauseFactory $clauseFactory @@ -52,19 +56,22 @@ class AstConverter implements AstConverterInterface * @param ReferenceTypeFactory $referenceTypeFactory * @param EntityAttributeList $entityAttributeList * @param ConfigInterface $config + * @param array $additionalAttributes */ public function __construct( ClauseFactory $clauseFactory, ConnectiveFactory $connectiveFactory, ReferenceTypeFactory $referenceTypeFactory, EntityAttributeList $entityAttributeList, - ConfigInterface $config + ConfigInterface $config, + array $additionalAttributes = ['min_price', 'max_price'] ) { $this->clauseFactory = $clauseFactory; $this->connectiveFactory = $connectiveFactory; $this->referenceTypeFactory = $referenceTypeFactory; $this->entityAttributeList = $entityAttributeList; $this->config = $config; + $this->additionalAttributes = $additionalAttributes; } /** @@ -131,6 +138,10 @@ private function getCatalogProductFields() } } + foreach ($this->additionalAttributes as $attribute) { + $fields[$attribute] = 'String'; + } + return $fields; } diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql.xml b/app/code/Magento/CatalogGraphQl/etc/graphql.xml index bee66ec84c178..69957566a092c 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql.xml @@ -298,6 +298,8 @@ <field xsi:type="ObjectInputField" name="description" type="FilterTypeInput" description="A detailed information about the product. The value can include simple HTML tags."/> <field xsi:type="ObjectInputField" name="short_description" type="FilterTypeInput" description="A short description of the product. Its use depends on the theme."/> <field xsi:type="ObjectInputField" name="price" type="FilterTypeInput" description="The numeric price of the product. Do not include the currency code."/> + <field xsi:type="ObjectInputField" name="min_price" type="FilterTypeInput" description="The numeric minimal price of the product. Do not include the currency code."/> + <field xsi:type="ObjectInputField" name="max_price" type="FilterTypeInput" description="The numeric maximal price of the product. Do not include the currency code."/> <field xsi:type="ObjectInputField" name="special_price" type="FilterTypeInput" description="The discounted price of the product"/> <field xsi:type="ObjectInputField" name="special_from_date" type="FilterTypeInput" description="The beginning date that a product has a special price."/> <field xsi:type="ObjectInputField" name="special_to_date" type="FilterTypeInput" description="The end date that a product has a special price."/> diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index e71b591839651..3b85984d5f919 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -71,4 +71,13 @@ </argument> </arguments> </type> + <virtualType name="Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\ProductFilterProcessor" type="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> + <arguments> + <argument name="customFilters" xsi:type="array"> + <item name="price" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\ProductPriceFilter</item> + <item name="min_price" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\ProductPriceFilter</item> + <item name="max_price" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\ProductPriceFilter</item> + </argument> + </arguments> + </virtualType> </config> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index 8a62dc85f8808..b1bfaa4719ff7 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -558,6 +558,90 @@ public function testProductLinks() $this->assertProductLinks($product, $response['products']['items'][0]['product_links'][0]); } + /** + * @magentoApiDataFixture Magento/Catalog/_files/products_list.php + */ + public function testProductPrices() + { + $firstProductSku = 'simple-249'; + $secondProductSku = 'simple-156'; + $query = <<<QUERY + { + products(filter: {min_price: {gt: "100.0"}, max_price: {gt: "150.0", lt: "250.0"}}) + { + items { + attribute_set_id + created_at + id + name + price { + minimalPrice { + amount { + value + currency + } + adjustments { + amount { + value + currency + } + code + description + } + } + maximalPrice { + amount { + value + currency + } + adjustments { + amount { + value + currency + } + code + description + } + } + regularPrice { + amount { + value + currency + } + adjustments { + amount { + value + currency + } + code + description + } + } + } + sku + type_id + updated_at + ... on PhysicalProductInterface { + weight + } + } + } + } +QUERY; + + $response = $this->graphQlQuery($query); + /** + * @var ProductRepositoryInterface $productRepository + */ + $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); + $firstProduct = $productRepository->get($firstProductSku, false, null, true); + $secondProduct = $productRepository->get($secondProductSku, false, null, true); + self::assertNotNull($response['products']['items'][0]['price'], "price must be not null"); + self::assertCount(2, $response['products']['items']); + $this->assertBaseFields($firstProduct, $response['products']['items'][0]); + $this->assertBaseFields($secondProduct, $response['products']['items'][1]); + } + /** * @param ProductInterface $product * @param array $actualResponse @@ -863,11 +947,11 @@ private function assertResponseFields($actualResponse, $assertionMap) ? $assertionData['expected_value'] : $assertionData; $responseField = isset($assertionData['response_field']) ? $assertionData['response_field'] : $key; - $this->assertNotNull( + self::assertNotNull( $expectedValue, "Value of '{$responseField}' field must not be NULL" ); - $this->assertEquals( + self::assertEquals( $expectedValue, $actualResponse[$responseField], "Value of '{$responseField}' field in response does not match expected value: " diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_list.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_list.php new file mode 100644 index 0000000000000..f5dfb74b71a68 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_list.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Model\Product::class); +$product + ->setTypeId('simple') + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Wrong Simple Product') + ->setSku('wrong-simple') + ->setPrice(300) + ->setWeight(10) + ->setSpecialPrice(90) + ->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 22, 'is_in_stock' => 1]) + ->setQty(22) + ->save(); + +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Model\Product::class); +$product + ->setTypeId('simple') + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('First Simple Product') + ->setSku('simple-249') + ->setPrice(249.9) + ->setSpecialPrice(153) + ->setWeight(10) + ->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 22, 'is_in_stock' => 1]) + ->setQty(22) + ->save(); + +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Model\Product::class); +$product + ->setTypeId('simple') + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setWeight(10) + ->setName('Second Simple Product') + ->setSku('simple-156') + ->setPrice(156) + ->setSpecialPrice(156) + ->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 22, 'is_in_stock' => 1]) + ->setQty(22) + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_list_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_list_rollback.php new file mode 100644 index 0000000000000..a0a7a912ff244 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_list_rollback.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** + * @var Magento\Catalog\Api\ProductRepositoryInterface $productRepository + */ +$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); +try { + $product = $productRepository->get('wrong-simple', false, null, true); + $productRepository->delete($product); +} catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + //Product already removed +} + +try { + $customDesignProduct = $productRepository->get('simple-156', false, null, true); + $productRepository->delete($customDesignProduct); +} catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + //Product already removed +} + +try { + $customDesignProduct = $productRepository->get('simple-249', false, null, true); + $productRepository->delete($customDesignProduct); +} catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + //Product already removed +} + + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); From 3a48198c3aa3c1aecdbe061e081c947dbe667ec0 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 14 Mar 2018 13:31:04 -0500 Subject: [PATCH 071/668] MAGETWO-89031: Make all graphql methods to return strict type - adding strict typing --- .../Model/Resolver/Products.php | 9 +- .../Products/FilterArgument/AstConverter.php | 4 +- .../Magento/CatalogGraphQl/etc/graphql/di.xml | 17 --- .../Model/Resolver/Customer.php | 9 +- .../Resolver/CustomAttributeMetadata.php | 9 +- .../Magento/GraphQl/Model/SchemaGenerator.php | 9 -- .../Model/Resolver/UrlRewrite.php | 9 +- .../Argument/ArgumentValueInterface.php | 2 + .../Argument/AstConverterInterface.php | 5 +- .../GraphQl/Argument/Filter/Clause.php | 12 +- .../Argument/Filter/Clause/ReferenceType.php | 7 +- .../Filter/Clause/ReferenceTypeFactory.php | 9 +- .../GraphQl/Argument/Filter/ClauseFactory.php | 4 +- .../GraphQl/Argument/Filter/Connective.php | 6 +- .../Argument/Filter/ConnectiveFactory.php | 4 +- .../Argument/Filter/FilterArgumentValue.php | 3 +- .../Filter/FilterArgumentValueFactory.php | 4 +- .../Filter/FilterArgumentValueInterface.php | 4 +- .../GraphQl/Argument/Filter/Operator.php | 6 +- .../ArgumentApplier/CurrentPage.php | 4 +- .../SearchCriteria/ArgumentApplier/Filter.php | 4 +- .../ArgumentApplier/PageSize.php | 4 +- .../SearchCriteria/ArgumentApplier/Search.php | 3 +- .../SearchCriteria/ArgumentApplier/Sort.php | 4 +- .../SearchCriteria/ArgumentApplierFactory.php | 3 +- .../ArgumentApplierInterface.php | 3 +- .../Argument/SearchCriteria/Builder.php | 3 +- .../SearchCriteria/FilterGroupFactory.php | 8 +- .../GraphQl/Argument/ValueParserInterface.php | 7 +- .../Config/Common/Converter/XmlConverter.php | 2 +- .../GraphQl/Config/Common/Reader.php | 2 +- .../Framework/GraphQl/Config/Converter.php | 2 +- .../Framework/GraphQl/Config/FieldConfig.php | 103 ------------------ .../GraphQlAuthorizationException.php | 5 +- .../Exception/GraphQlInputException.php | 5 +- .../GraphQlNoSuchEntityException.php | 5 +- .../Framework/GraphQl/Query/EnumLookup.php | 9 +- .../GraphQl/Resolver/ResolverInterface.php | 12 +- .../Output/ElementMapper/Formatter/Fields.php | 9 -- 39 files changed, 132 insertions(+), 197 deletions(-) delete mode 100644 lib/internal/Magento/Framework/GraphQl/Config/FieldConfig.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php index 0778e164731de..2f5c38f28102d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php @@ -52,8 +52,13 @@ public function __construct( /** * {@inheritdoc} */ - public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) - { + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ) : ?array { $searchCriteria = $this->searchCriteriaBuilder->build($args); if (!isset($args['search']) && !isset($args['filter'])) { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php index bcc8db4b69d6c..03caa76c98a4c 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\CatalogGraphQl\Model\Resolver\Products\FilterArgument; use Magento\Framework\GraphQl\Argument\AstConverterInterface; @@ -141,7 +143,7 @@ private function getCatalogProductFields() * @param array $arguments * @return Connective */ - public function convert(string $entityType, $arguments) + public function convert(string $entityType, array $arguments) : Connective { $filters = $this->getClausesFromAst( $this->referenceTypeFactory->create($entityType), diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index e71b591839651..32717bfc151c4 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -6,23 +6,6 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <type name="Magento\Framework\GraphQl\Config\FieldConfig"> - <arguments> - <argument name="config" xsi:type="array"> - <item name="products" xsi:type="array"> - <item name="filter" xsi:type="array"> - <item name="valueParser" xsi:type="object">Magento\CatalogGraphQl\Model\Resolver\Products\FilterArgument\ValueParser</item> - </item> - <item name="pageSize" xsi:type="array"> - <item name="defaultValue" xsi:type="string">20</item> - </item> - <item name="currentPage" xsi:type="array"> - <item name="defaultValue" xsi:type="string">1</item> - </item> - </item> - </argument> - </arguments> - </type> <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterComposite"> <arguments> <argument name="formatterInstances" xsi:type="array"> diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php index 3c8c41871598c..72ded3817c353 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php @@ -36,8 +36,13 @@ public function __construct( /** * {@inheritdoc} */ - public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) - { + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ) : ?array { /** @var ResolverContextInterface $context */ if ((!$context->getUserId()) || $context->getUserType() == 4) { throw new GraphQlAuthorizationException( diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php b/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php index ca09cde3288fc..6f627eb323d28 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php @@ -37,8 +37,13 @@ public function __construct(Type $type) /** * {@inheritDoc} */ - public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) - { + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ) : ?array { $attributes['items'] = null; /** @var ArgumentInterface $attributeInputs */ $attributeInputs = $args['attributes']; diff --git a/app/code/Magento/GraphQl/Model/SchemaGenerator.php b/app/code/Magento/GraphQl/Model/SchemaGenerator.php index f4898cc836e3a..7f1dd151160df 100644 --- a/app/code/Magento/GraphQl/Model/SchemaGenerator.php +++ b/app/code/Magento/GraphQl/Model/SchemaGenerator.php @@ -7,7 +7,6 @@ namespace Magento\GraphQl\Model; use Magento\Framework\GraphQl\Type\SchemaFactory; -use Magento\Framework\GraphQl\Config\FieldConfig; use Magento\GraphQl\Model\Type\Generator; use Magento\Framework\GraphQl\ArgumentFactory; use Magento\Framework\GraphQl\TypeFactory; @@ -27,11 +26,6 @@ class SchemaGenerator implements SchemaGeneratorInterface */ private $argumentFactory; - /** - * @var FieldConfig - */ - private $fieldConfig; - /** * @var TypeFactory */ @@ -45,20 +39,17 @@ class SchemaGenerator implements SchemaGeneratorInterface /** * @param Generator $typeGenerator * @param ArgumentFactory $argumentFactory - * @param FieldConfig $fieldConfig * @param TypeFactory $typeFactory * @param SchemaFactory $schemaFactory */ public function __construct( Generator $typeGenerator, ArgumentFactory $argumentFactory, - FieldConfig $fieldConfig, TypeFactory $typeFactory, SchemaFactory $schemaFactory ) { $this->typeGenerator = $typeGenerator; $this->argumentFactory = $argumentFactory; - $this->fieldConfig = $fieldConfig; $this->typeFactory = $typeFactory; $this->schemaFactory = $schemaFactory; } diff --git a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php index aab5dec66669a..f83f6dd7d1ce2 100644 --- a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php +++ b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php @@ -42,8 +42,13 @@ public function __construct( /** * {@inheritdoc} */ - public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) - { + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ) : ?array { if (isset($args['url'])) { $urlRewrite = $this->findCanonicalUrl($args['url']); if ($urlRewrite) { diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/ArgumentValueInterface.php b/lib/internal/Magento/Framework/GraphQl/Argument/ArgumentValueInterface.php index 53035b8e8daa3..708b72755b7f5 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/ArgumentValueInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/ArgumentValueInterface.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\Framework\GraphQl\Argument; /** diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/AstConverterInterface.php b/lib/internal/Magento/Framework/GraphQl/Argument/AstConverterInterface.php index 21a945593bda1..82ab099dd4e71 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/AstConverterInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/AstConverterInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Argument; @@ -17,5 +18,5 @@ interface AstConverterInterface * @param array $arguments * @return Connective */ - public function convert(string $entityType, $arguments); -} \ No newline at end of file + public function convert(string $entityType, array $arguments) : Connective; +} diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Clause.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Clause.php index 5cab7d06fae3c..23e60b409af83 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Clause.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Clause.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\Framework\GraphQl\Argument\Filter; use Magento\Framework\GraphQl\Argument\Filter\Clause\ReferenceType; @@ -57,7 +59,7 @@ public function __construct( * * @return ReferenceType */ - public function getReferencedType() + public function getReferencedType() : ReferenceType { return $this->referenceType; } @@ -67,7 +69,7 @@ public function getReferencedType() * * @return string */ - public function getFieldName() + public function getFieldName() : string { return $this->fieldName; } @@ -77,7 +79,7 @@ public function getFieldName() * * @return string */ - public function getClauseType() + public function getClauseType(): string { return $this->clauseType; } @@ -85,9 +87,9 @@ public function getClauseType() /** * Get the clause value * - * @return string|array + * @return string */ - public function getClauseValue() + public function getClauseValue() : string { return $this->clauseValue; } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Clause/ReferenceType.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Clause/ReferenceType.php index 5ae028043a61a..d910c02b3c889 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Clause/ReferenceType.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Clause/ReferenceType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Argument\Filter\Clause; @@ -46,7 +47,7 @@ public function __construct( * * @return ReferenceType */ - public function getReferenceType() + public function getReferenceType() : ReferenceType { return $this->referenceType; } @@ -56,7 +57,7 @@ public function getReferenceType() * * @return string */ - public function getLinkField() + public function getLinkField() : string { return $this->linkField; } @@ -66,7 +67,7 @@ public function getLinkField() * * @return string */ - public function getEntityType() + public function getEntityType() : string { return $this->entityType; } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Clause/ReferenceTypeFactory.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Clause/ReferenceTypeFactory.php index 3d683d85cceff..c26dc6f6c58b4 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Clause/ReferenceTypeFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Clause/ReferenceTypeFactory.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\Framework\GraphQl\Argument\Filter\Clause; use Magento\Framework\ObjectManagerInterface; @@ -34,8 +36,11 @@ public function __construct( * @param ReferenceType|null $referenceType * @return ReferenceType */ - public function create(string $entityType, string $linkField = null, ReferenceType $referenceType = null) - { + public function create( + string $entityType, + string $linkField = null, + ReferenceType $referenceType = null + ) : ? ReferenceType { return $this->objectManager->create( ReferenceType::class, [ diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/ClauseFactory.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/ClauseFactory.php index 2f3ac1c643144..62d75fe52e41e 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/ClauseFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/ClauseFactory.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\Framework\GraphQl\Argument\Filter; use Magento\Framework\ObjectManagerInterface; @@ -41,7 +43,7 @@ public function create( string $fieldName, string $clauseType, $clauseValue - ) { + ) : Clause { return $this->objectManager->create( Clause::class, [ diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Connective.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Connective.php index 99cfb26dfb367..8a98561b4ab43 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Connective.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Connective.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\Framework\GraphQl\Argument\Filter; /** @@ -39,7 +41,7 @@ public function __construct( * * @return Operator */ - public function getOperator() + public function getOperator() : Operator { return $this->operator; } @@ -49,7 +51,7 @@ public function getOperator() * * @return Connective[]|Clause[] */ - public function getConditions() + public function getConditions(): array { return $this->conditions; } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/ConnectiveFactory.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/ConnectiveFactory.php index feea0268180d9..71adc94e9bb29 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/ConnectiveFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/ConnectiveFactory.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\Framework\GraphQl\Argument\Filter; use Magento\Framework\ObjectManagerInterface; @@ -35,7 +37,7 @@ public function __construct( public function create( array $conditions, string $operator = null - ) { + ) : Connective { return $this->objectManager->create( Connective::class, [ diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValue.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValue.php index 353505207c03a..cfb4af85a4f58 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValue.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValue.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Argument\Filter; @@ -27,7 +28,7 @@ public function __construct(Connective $value) /** * {@inheritdoc} */ - public function getValue() + public function getValue() : Connective { return $this->value; } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueFactory.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueFactory.php index c2d855b750df5..51aaff2cc94ae 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueFactory.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\Framework\GraphQl\Argument\Filter; use Magento\Framework\ObjectManagerInterface; @@ -32,7 +34,7 @@ public function __construct( * @param Connective $connective * @return FilterArgumentValue */ - public function create(Connective $connective) + public function create(Connective $connective) : FilterArgumentValue { return $this->objectManager->create( FilterArgumentValue::class, diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueInterface.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueInterface.php index 8806069f9d0ec..51b7e67bc19e7 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueInterface.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\Framework\GraphQl\Argument\Filter; use Magento\Framework\GraphQl\Argument\ArgumentValueInterface; @@ -17,5 +19,5 @@ interface FilterArgumentValueInterface extends ArgumentValueInterface * * @return Connective */ - public function getValue(); + public function getValue() : Connective; } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Operator.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Operator.php index 2b71527d6bcc2..711ff66653a72 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Operator.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Operator.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\Framework\GraphQl\Argument\Filter; use Magento\Framework\Phrase; @@ -57,7 +59,7 @@ public function __construct($value = self::AND) * * @return array */ - public static function getOperators() + public static function getOperators() : array { $type = new \ReflectionClass(Operator::class); return $type->getConstants(); @@ -68,7 +70,7 @@ public static function getOperators() * * @return string */ - public function __toString() + public function __toString() : string { return strtoupper($this->value); } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/CurrentPage.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/CurrentPage.php index cb248b18d66f3..1de5d7ddb4d49 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/CurrentPage.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/CurrentPage.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Argument\SearchCriteria\ArgumentApplier; @@ -21,7 +22,7 @@ class CurrentPage implements ArgumentApplierInterface /** * {@inheritdoc} */ - public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) + public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) : SearchCriteriaInterface { if (is_int($argument) || is_string($argument)) { $searchCriteria->setCurrentPage($argument); @@ -30,5 +31,6 @@ public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument new Phrase('Argument %1 not of type Int', [$argument]) ); } + return $searchCriteria; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Filter.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Filter.php index c8b05d5beccd9..5da119bcf2382 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Filter.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Filter.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Argument\SearchCriteria\ArgumentApplier; @@ -44,7 +45,7 @@ public function __construct(AstConverterInterface $astConverter, FilterGroupFact /** * {@inheritdoc} */ - public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) + public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) : SearchCriteriaInterface { $filters = $this->astConverter->convert(\Magento\Catalog\Model\Product::ENTITY, $argument); if (!empty($filters)) { @@ -56,5 +57,6 @@ public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument new Phrase('Argument %1 not of type %2', [$argument->getName(), FilterArgumentValueInterface::class]) ); } + return $searchCriteria; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/PageSize.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/PageSize.php index 641d91e5dcccd..3f9dad6e7897b 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/PageSize.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/PageSize.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Argument\SearchCriteria\ArgumentApplier; @@ -21,7 +22,7 @@ class PageSize implements ArgumentApplierInterface /** * {@inheritdoc} */ - public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) + public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) : SearchCriteriaInterface { if (is_int($argument) || is_string($argument)) { $searchCriteria->setPageSize($argument); @@ -30,5 +31,6 @@ public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument new Phrase('Argument %1 not of type Int', [$argument]) ); } + return $searchCriteria; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Search.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Search.php index 233940de5af09..6b21e17981775 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Search.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Search.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Argument\SearchCriteria\ArgumentApplier; @@ -39,7 +40,7 @@ public function __construct(FilterBuilder $filterBuilder, FilterGroupBuilder $fi /** * {@inheritDoc} */ - public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) + public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) : SearchCriteriaInterface { $searchTerm = $argument; $searchTermFilter = $this->filterBuilder->setField('search_term')->setValue($searchTerm)->create(); diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php index d8c4e4bc63d0c..6ae71f241b3f6 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Argument\SearchCriteria\ArgumentApplier; @@ -36,7 +37,7 @@ public function __construct($sortOrderBuilder = null) /** * {@inheritdoc} */ - public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) + public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) : SearchCriteriaInterface { if (is_array($argument)) { $sortOrders = []; @@ -52,5 +53,6 @@ public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument new Phrase('Argument %1 not of type array or null', [$argument]) ); } + return $searchCriteria; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierFactory.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierFactory.php index 6d4753b4d7c02..5c6ef4069369d 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierFactory.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Argument\SearchCriteria; @@ -34,7 +35,7 @@ public function __construct( * @return ArgumentApplierInterface * @throws \LogicException */ - public function create(string $argumentName) + public function create(string $argumentName) : ArgumentApplierInterface { $appliers = [ ArgumentApplier\Filter::ARGUMENT_NAME => ArgumentApplier\Filter::class, diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierInterface.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierInterface.php index 88be790d1e8ee..dc31dcffc51bc 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Argument\SearchCriteria; @@ -21,5 +22,5 @@ interface ArgumentApplierInterface * @param mixed $argument * @return SearchCriteriaInterface */ - public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument); + public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) : SearchCriteriaInterface; } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/Builder.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/Builder.php index 1c35d1bdd95ae..3a6b7c1747f5a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/Builder.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/Builder.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Argument\SearchCriteria; @@ -40,7 +41,7 @@ public function __construct( * @param array $arguments * @return SearchCriteriaInterface */ - public function build(array $arguments) + public function build(array $arguments) : SearchCriteriaInterface { $searchCriteria = $this->searchCriteriaFactory->create(); foreach ($arguments as $argumentName => $argument) { diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/FilterGroupFactory.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/FilterGroupFactory.php index 6b9ea5090c89f..9f92633aa2289 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/FilterGroupFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/FilterGroupFactory.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Argument\SearchCriteria; @@ -14,6 +15,7 @@ use Magento\Framework\GraphQl\Argument\Filter\FilterArgumentValueInterface; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\Phrase; +use Magento\Framework\Api\Search\FilterGroup; /** * Class FilterGroupFactory @@ -45,7 +47,7 @@ public function __construct( * @return \Magento\Framework\Api\Search\FilterGroup[] * @throws GraphQlInputException */ - public function create(Connective $arguments) + public function create(Connective $arguments) : array { $filters = $arguments; /** @var \Magento\Framework\Api\Search\FilterGroup[] $searchCriteriaFilterGroups */ @@ -72,10 +74,10 @@ public function create(Connective $arguments) * Process an AST Connective * * @param Connective $connective - * @return \Magento\Framework\Api\Search\FilterGroup + * @return FilterGroup * @throws GraphQlInputException */ - private function processConnective(Connective $connective) + private function processConnective(Connective $connective) : FilterGroup { foreach ($connective->getConditions() as $subNode) { if ($subNode instanceof Clause) { diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/ValueParserInterface.php b/lib/internal/Magento/Framework/GraphQl/Argument/ValueParserInterface.php index bdca461058fc4..dfb9e1df9ff56 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/ValueParserInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/ValueParserInterface.php @@ -3,18 +3,19 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Framework\GraphQl\Argument; /** - * Class responsable for transforming an argument value from one array type to a complex or other type + * Class responsible for transforming an argument value from one array type to a complex or other type */ interface ValueParserInterface { /** * Parse an argument value from an array or scalar to a ArgumentValueInterface * - * @param array|int|string|float|bool $value - * @return ArgumentValueInterface|ArgumentValueInterface[]|int|int[]|string|string[]|float|float[]|bool + * @param array|int|string|float|bool|mixed $value + * @return ArgumentValueInterface|ArgumentValueInterface[]|int|int[]|string|string[]|float|float[]|bool|mixed */ public function parse($value); } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Common/Converter/XmlConverter.php b/lib/internal/Magento/Framework/GraphQl/Config/Common/Converter/XmlConverter.php index 6a847e0311257..64b244d69391e 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Common/Converter/XmlConverter.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Common/Converter/XmlConverter.php @@ -54,7 +54,7 @@ private function convertNodeToArray(\DOMNode $source) * @param \DOMDocument $source * @return array */ - public function convert($source) + public function convert($source) : array { return $this->convertNodeToArray($source); } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php b/lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php index c9c9217d1b579..929d23653f372 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php @@ -33,7 +33,7 @@ public function __construct( * @param string|null $scope * @return array */ - public function read($scope = null) + public function read($scope = null) : array { $output = []; foreach ($this->readers as $reader) { diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter.php index 5e18ce4bbb2a5..ad28e7e4f46cb 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Converter.php @@ -41,7 +41,7 @@ public function __construct(XmlConverter $xmlConverter, NormalizerInterface $nor * @param \DOMDocument $source * @return array */ - public function convert($source) + public function convert($source) : array { return $this->normalizer->normalize($this->xmlConverter->convert($source)); } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/FieldConfig.php b/lib/internal/Magento/Framework/GraphQl/Config/FieldConfig.php deleted file mode 100644 index b2d028686bd6b..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Config/FieldConfig.php +++ /dev/null @@ -1,103 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Config; - -/** - * Class that stores configuration for processing value of arguments for GraphQl fields - */ -class FieldConfig -{ - /** - * Map as array for classes that represent field arguments - * - * @var array - */ - private $config = []; - - /** - * @var array - */ - private $instances = []; - - /** - * @var ArgumentConfigFactory - */ - private $argumentConfigFactory; - - /** - * @param ArgumentConfigFactory $argumentConfigFactory - * @param array $config - */ - public function __construct(ArgumentConfigFactory $argumentConfigFactory, array $config = []) - { - $this->config = $config; - $this->argumentConfigFactory = $argumentConfigFactory; - } - - /** - * Returns a field configuration that is configured through DI - * - * @param string $fieldName - * @param array $arguments - * @return ArgumentConfig[] - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ - public function getFieldConfig(string $fieldName, array $arguments) : array - { - if (isset($this->instances[$fieldName])) { - return $this->instances[$fieldName]; - } - if (isset($this->config[$fieldName])) { - $this->processConfiguredField($fieldName, $arguments); - } else { - foreach (array_keys($arguments) as $argument) { - $this->instances[$fieldName][$argument] = $this->argumentConfigFactory->create([ - 'defaultValue' => null, - 'valueParser' => null - ]); - } - } - //not all fields have arguments - if (isset($this->instances[$fieldName])) { - return $this->instances[$fieldName]; - } else { - return []; - } - } - - /** - * Configure field and create arguments instance - * - * @param string $fieldName - * @param array $arguments - */ - private function processConfiguredField(string $fieldName, array $arguments) : void - { - $this->instances[$fieldName] = []; - foreach ($this->config[$fieldName] as $argumentName => $fieldConfig) { - $this->instances[$fieldName][$argumentName] = $this->argumentConfigFactory->create( - [ - 'defaultValue' => isset($fieldConfig['defaultValue']) ? $fieldConfig['defaultValue'] : null, - 'valueParser'=> isset($fieldConfig['valueParser']) - ? $fieldConfig['valueParser'] - : null - ] - ); - } - foreach (array_keys($arguments) as $argumentName) { - if (!isset($this->instances[$fieldName][$argumentName])) { - $this->instances[$fieldName][$argumentName] = $this->argumentConfigFactory->create( - [ - 'defaultValue' => null, - 'valueParser'=> null - ] - ); - } - } - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php index 1cc47bb0db12e..0e660c962c3d5 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Exception; @@ -38,7 +39,7 @@ public function __construct(Phrase $phrase, \Exception $cause = null, $code = 0, /** * {@inheritDoc} */ - public function isClientSafe() + public function isClientSafe() : bool { return $this->isSafe; } @@ -46,7 +47,7 @@ public function isClientSafe() /** * {@inheritDoc} */ - public function getCategory() + public function getCategory() : string { return self::EXCEPTION_CATEGORY; } diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php index b05120f47938a..745c30e144fa7 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Exception; @@ -38,7 +39,7 @@ public function __construct(Phrase $phrase, \Exception $cause = null, $code = 0, /** * {@inheritDoc} */ - public function isClientSafe() + public function isClientSafe() : bool { return $this->isSafe; } @@ -46,7 +47,7 @@ public function isClientSafe() /** * {@inheritDoc} */ - public function getCategory() + public function getCategory() : string { return self::EXCEPTION_CATEGORY; } diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php index 26bfddecc3376..3e62389ebe997 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Exception; @@ -38,7 +39,7 @@ public function __construct(Phrase $phrase, \Exception $cause = null, $code = 0, /** * {@inheritDoc} */ - public function isClientSafe() + public function isClientSafe() : bool { return $this->isSafe; } @@ -46,7 +47,7 @@ public function isClientSafe() /** * {@inheritDoc} */ - public function getCategory() + public function getCategory() : string { return self::EXCEPTION_CATEGORY; } diff --git a/lib/internal/Magento/Framework/GraphQl/Query/EnumLookup.php b/lib/internal/Magento/Framework/GraphQl/Query/EnumLookup.php index b9d9fb9784183..e1e2ebb9f49f1 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/EnumLookup.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/EnumLookup.php @@ -38,14 +38,14 @@ public function __construct(ConfigInterface $typeConfig, DataMapperInterface $en } /** - * Convert a field value from a db query to an enum value declared as an item in the graphql.xml schema + * Convert a field value from a db query to an enum value declared as an item in the graphql schema * * @param string $enumName - * @param int|string|bool|float|null $fieldValue - * @return int|string|bool|float|null + * @param string $fieldValue + * @return string|null * @throws \Magento\Framework\Exception\RuntimeException */ - public function getEnumValueFromField(string $enumName, $fieldValue) : string + public function getEnumValueFromField(string $enumName, string $fieldValue) : ?string { $priceViewEnum = $this->typeConfig->getTypeStructure($enumName); if ($priceViewEnum instanceof Enum) { @@ -60,5 +60,6 @@ public function getEnumValueFromField(string $enumName, $fieldValue) : string new Phrase('Enum type "%1" not defined', [$enumName]) ); } + return null; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php b/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php index 7c5b74fa52378..615bf78781d98 100644 --- a/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Resolver; @@ -22,7 +23,14 @@ interface ResolverInterface * @param array|null $args * @param $context * @param ResolveInfo $info - * @return mixed + * @throws \Exception + * @return array|null */ - public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info); + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ) : ?array; } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php index d372b79d452d3..6e8fa0a347fea 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php @@ -17,7 +17,6 @@ use Magento\Framework\GraphQl\TypeFactory; use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\GraphQl\Config\FieldConfig; use Magento\Framework\GraphQl\Type\Definition\ScalarTypes; use Magento\Framework\GraphQl\Config\Data\WrappedTypeProcessor; @@ -31,11 +30,6 @@ class Fields implements FormatterInterface */ private $objectManager; - /** - * @var FieldConfig - */ - private $fieldConfig; - /** * @var ArgumentFactory */ @@ -68,7 +62,6 @@ class Fields implements FormatterInterface /** * @param ObjectManagerInterface $objectManager - * @param FieldConfig $fieldConfig * @param ArgumentFactory $argumentFactory * @param OutputMapper $outputMapper * @param InputMapper $inputMapper @@ -78,7 +71,6 @@ class Fields implements FormatterInterface */ public function __construct( ObjectManagerInterface $objectManager, - FieldConfig $fieldConfig, ArgumentFactory $argumentFactory, OutputMapper $outputMapper, InputMapper $inputMapper, @@ -87,7 +79,6 @@ public function __construct( WrappedTypeProcessor $wrappedTypeProcessor ) { $this->objectManager = $objectManager; - $this->fieldConfig = $fieldConfig; $this->argumentFactory = $argumentFactory; $this->outputMapper = $outputMapper; $this->inputMapper = $inputMapper; From 71637f09169981ca6e59aa3c7484d19df40b2a76 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 14 Mar 2018 14:08:56 -0500 Subject: [PATCH 072/668] MAGETWO-89091: CE edition - Update composer dependencies - update colinmollenhour/cache-backend-file to 1.4.1 --- composer.json | 2 +- composer.lock | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index f4bf0e9cd2376..ca954efba6b03 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,7 @@ "ext-zip": "*", "lib-libxml": "*", "braintree/braintree_php": "3.22.0", - "colinmollenhour/cache-backend-file": "1.4", + "colinmollenhour/cache-backend-file": "~1.4.1", "colinmollenhour/cache-backend-redis": "1.10.2", "colinmollenhour/credis": "1.6", "colinmollenhour/php-redis-session-abstract": "~1.3.8", diff --git a/composer.lock b/composer.lock index f40d49ed7b1d0..593caff2199ee 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "ab176287e06df4501eabb23d308959cb", - "content-hash": "fc4d6d51bf1d69473aab77b19380d74e", + "hash": "fa404416b0dfa6063cda27d6b6ea40be", + "content-hash": "80e74dc347ccd2c94e3b53a5d3dca08d", "packages": [ { "name": "braintree/braintree_php", @@ -56,21 +56,18 @@ }, { "name": "colinmollenhour/cache-backend-file", - "version": "1.4", + "version": "v1.4.1", "source": { "type": "git", "url": "https://github.com/colinmollenhour/Cm_Cache_Backend_File.git", - "reference": "51251b80a817790eb624fbe2afc882c14f3c4fb0" + "reference": "3146110d4d0f79e016a4f99c36794d5ed50c4652" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_File/zipball/51251b80a817790eb624fbe2afc882c14f3c4fb0", - "reference": "51251b80a817790eb624fbe2afc882c14f3c4fb0", + "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_File/zipball/3146110d4d0f79e016a4f99c36794d5ed50c4652", + "reference": "3146110d4d0f79e016a4f99c36794d5ed50c4652", "shasum": "" }, - "require": { - "magento-hackathon/magento-composer-installer": "*" - }, "type": "magento-module", "autoload": { "classmap": [ @@ -88,7 +85,7 @@ ], "description": "The stock Zend_Cache_Backend_File backend has extremely poor performance for cleaning by tags making it become unusable as the number of cached items increases. This backend makes many changes resulting in a huge performance boost, especially for tag cleaning.", "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_File", - "time": "2016-05-02 16:24:47" + "time": "2018-03-02 17:44:39" }, { "name": "colinmollenhour/cache-backend-redis", From 5d9f1f05b1e651f7c2876267e96d7e5024f733ef Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 14 Mar 2018 14:20:11 -0500 Subject: [PATCH 073/668] MAGETWO-89091: CE edition - Update composer dependencies - update zendframework/zend-code to 3.1.0 and zendframework/zend-mail to 2.9.0 --- composer.json | 4 ++-- composer.lock | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/composer.json b/composer.json index ca954efba6b03..fae96b345633e 100644 --- a/composer.json +++ b/composer.json @@ -57,7 +57,7 @@ "tubalmartin/cssmin": "4.1.0", "webonyx/graphql-php": "^0.11.1", "zendframework/zend-captcha": "^2.7.1", - "zendframework/zend-code": "^3.1.0", + "zendframework/zend-code": "~3.1.0", "zendframework/zend-config": "^2.6.0", "zendframework/zend-console": "^2.6.0", "zendframework/zend-crypt": "^2.6.0", @@ -69,7 +69,7 @@ "zendframework/zend-i18n": "^2.7.3", "zendframework/zend-json": "^2.6.1", "zendframework/zend-log": "^2.9.1", - "zendframework/zend-mail": "^2.8.0", + "zendframework/zend-mail": "^2.9.0", "zendframework/zend-modulemanager": "^2.7", "zendframework/zend-mvc": "~2.6.3", "zendframework/zend-serializer": "^2.7.2", diff --git a/composer.lock b/composer.lock index 593caff2199ee..a3d495c5216c5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "fa404416b0dfa6063cda27d6b6ea40be", - "content-hash": "80e74dc347ccd2c94e3b53a5d3dca08d", + "hash": "713d37577c51e070639ac6ccff118414", + "content-hash": "0e32ec1f156e383fef6f5a64de8c514e", "packages": [ { "name": "braintree/braintree_php", @@ -2037,27 +2037,27 @@ }, { "name": "zendframework/zend-code", - "version": "3.3.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-code.git", - "reference": "6b1059db5b368db769e4392c6cb6cc139e56640d" + "reference": "2899c17f83a7207f2d7f53ec2f421204d3beea27" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-code/zipball/6b1059db5b368db769e4392c6cb6cc139e56640d", - "reference": "6b1059db5b368db769e4392c6cb6cc139e56640d", + "url": "https://api.github.com/repos/zendframework/zend-code/zipball/2899c17f83a7207f2d7f53ec2f421204d3beea27", + "reference": "2899c17f83a7207f2d7f53ec2f421204d3beea27", "shasum": "" }, "require": { - "php": "^7.1", + "php": "^5.6 || 7.0.0 - 7.0.4 || ^7.0.6", "zendframework/zend-eventmanager": "^2.6 || ^3.0" }, "require-dev": { "doctrine/annotations": "~1.0", "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "zendframework/zend-coding-standard": "^1.0.0", + "phpunit/phpunit": "^4.8.21", + "squizlabs/php_codesniffer": "^2.5", "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "suggest": { @@ -2067,8 +2067,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev", - "dev-develop": "3.3-dev" + "dev-master": "3.1-dev", + "dev-develop": "3.2-dev" } }, "autoload": { @@ -2086,7 +2086,7 @@ "code", "zf2" ], - "time": "2017-10-20 15:21:32" + "time": "2016-10-24 13:23:32" }, { "name": "zendframework/zend-config", From d901f300ef1ca92ba0f29a42d4437e1025dcb031 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 14 Mar 2018 14:49:22 -0500 Subject: [PATCH 074/668] MAGETWO-89091: CE edition - Update composer dependencies - revert change to code generater test after update zendframework/zend-code to 3.1.0 --- .../Api/Test/Unit/Code/Generator/_files/SampleMapper.txt | 4 ++-- .../app/code/Magento/SomeModule/Model/SevenInterface.php | 2 +- .../Test/Unit/Code/Generator/_files/SampleFactory.txt | 2 +- .../Test/Unit/Code/Generator/_files/SampleRepository.txt | 4 ++-- .../Test/Unit/Code/Generator/_files/TSampleRepository.txt | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleMapper.txt b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleMapper.txt index ec0397dac9e2d..21b81bad090e5 100644 --- a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleMapper.txt +++ b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleMapper.txt @@ -17,9 +17,9 @@ class SampleMapper * * @var array */ - protected $registry = [ + protected $registry = array( - ]; + ); /** * Mapper constructor diff --git a/lib/internal/Magento/Framework/Code/Test/Unit/_files/app/code/Magento/SomeModule/Model/SevenInterface.php b/lib/internal/Magento/Framework/Code/Test/Unit/_files/app/code/Magento/SomeModule/Model/SevenInterface.php index 66c74bbf04e6f..d2539c9b73153 100644 --- a/lib/internal/Magento/Framework/Code/Test/Unit/_files/app/code/Magento/SomeModule/Model/SevenInterface.php +++ b/lib/internal/Magento/Framework/Code/Test/Unit/_files/app/code/Magento/SomeModule/Model/SevenInterface.php @@ -32,7 +32,7 @@ interface SevenInterface extends \Magento\Framework\Code\Generator\CodeGenerator * @param array $data * @return TestThree */ - public static function testMethod1(array &$data = []); + public static function testMethod1(array &$data = array()); /** * Method short description diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleFactory.txt b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleFactory.txt index ad78440c5c9f2..37960239cb2c3 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleFactory.txt +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleFactory.txt @@ -37,7 +37,7 @@ class SampleFactory * @param array $data * @return \Magento\Framework\ObjectManager\Code\Generator\Sample */ - public function create(array $data = []) + public function create(array $data = array()) { return $this->_objectManager->create($this->_instanceName, $data); } diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt index 7c5fc6f97eef1..5cc2e35598b89 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt @@ -27,9 +27,9 @@ class SampleRepository implements SampleRepositoryInterface * * @var array */ - protected $registry = [ + protected $registry = array( - ]; + ); /** * Extension attributes join processor. diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/TSampleRepository.txt b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/TSampleRepository.txt index 10315080aefac..bb2da3499c14d 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/TSampleRepository.txt +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/TSampleRepository.txt @@ -27,9 +27,9 @@ class TSampleRepository implements TSampleRepositoryInterface * * @var array */ - protected $registry = [ + protected $registry = array( - ]; + ); /** * Extension attributes join processor. From 5f72687f46daac521996f45c78cc9a660ce50324 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 14 Mar 2018 14:55:23 -0500 Subject: [PATCH 075/668] MAGETWO-89031: Make all graphql methods to return strict type - removing Arguments abstraction, types and interfaces & usages --- .../Products/FilterArgument/ValueParser.php | 42 ------------- .../Resolver/CustomAttributeMetadata.php | 4 +- .../GraphQl/Model/ResolverInterface.php | 23 -------- .../Magento/GraphQl/Model/SchemaGenerator.php | 9 --- app/code/Magento/GraphQl/etc/di.xml | 1 - .../Magento/Framework/GraphQl/Argument.php | 46 --------------- .../Argument/ArgumentValueInterface.php | 16 ----- .../Argument/Filter/FilterArgumentValue.php | 35 ----------- .../Filter/FilterArgumentValueFactory.php | 46 --------------- .../Filter/FilterArgumentValueInterface.php | 23 -------- .../ArgumentApplier/CurrentPage.php | 1 - .../SearchCriteria/ArgumentApplier/Filter.php | 15 +---- .../ArgumentApplier/PageSize.php | 3 +- .../SearchCriteria/ArgumentApplier/Search.php | 1 - .../SearchCriteria/ArgumentApplier/Sort.php | 1 - .../ArgumentApplierInterface.php | 1 - .../Argument/SearchCriteria/Builder.php | 1 - .../SearchCriteria/FilterGroupFactory.php | 1 - .../GraphQl/Argument/ValueParserInterface.php | 21 ------- .../Framework/GraphQl/ArgumentFactory.php | 47 --------------- .../Framework/GraphQl/ArgumentInterface.php | 29 --------- .../GraphQl/Config/ArgumentConfig.php | 59 ------------------- .../Output/ElementMapper/Formatter/Fields.php | 9 --- 23 files changed, 5 insertions(+), 429 deletions(-) delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/ValueParser.php delete mode 100644 app/code/Magento/GraphQl/Model/ResolverInterface.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Argument.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Argument/ArgumentValueInterface.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValue.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueFactory.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueInterface.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Argument/ValueParserInterface.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/ArgumentFactory.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/ArgumentInterface.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Config/ArgumentConfig.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/ValueParser.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/ValueParser.php deleted file mode 100644 index da6fc99b378c0..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/ValueParser.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\CatalogGraphQl\Model\Resolver\Products\FilterArgument; - -use Magento\Framework\GraphQl\Argument\Filter\FilterArgumentValueFactory; -use Magento\Framework\GraphQl\Argument\ValueParserInterface; - -/** - * Parses a mixed value to a FindArgumentValue - */ -class ValueParser implements ValueParserInterface -{ - /** @var AstConverter */ - private $clauseConverter; - - /** @var FilterArgumentValueFactory */ - private $filterArgumentValueFactory; - - /** - * @param AstConverter $clauseConverter - * @param FilterArgumentValueFactory $filterArgumentValueFactory - */ - public function __construct( - AstConverter $clauseConverter, - FilterArgumentValueFactory $filterArgumentValueFactory - ) { - $this->clauseConverter = $clauseConverter; - $this->filterArgumentValueFactory = $filterArgumentValueFactory; - } - - /** - * {@inheritdoc} - */ - public function parse($value) - { - $filters = $this->clauseConverter->convert(\Magento\Catalog\Model\Product::ENTITY, $value); - return $this->filterArgumentValueFactory->create($filters); - } -} diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php b/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php index 6f627eb323d28..1f3ce3c7b31d8 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php @@ -9,7 +9,6 @@ use GraphQL\Type\Definition\ResolveInfo; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\GraphQl\ArgumentInterface; use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; @@ -45,7 +44,6 @@ public function resolve( ResolveInfo $info ) : ?array { $attributes['items'] = null; - /** @var ArgumentInterface $attributeInputs */ $attributeInputs = $args['attributes']; foreach ($attributeInputs as $attribute) { if (!isset($attribute['attribute_code']) || !isset($attribute['entity_type'])) { @@ -87,7 +85,7 @@ public function resolve( } /** - * Create GraphQL input exception for an invalid AttributeInput ArgumentValueInterface + * Create GraphQL input exception for an invalid attribute input * * @param array $attribute * @return GraphQlInputException diff --git a/app/code/Magento/GraphQl/Model/ResolverInterface.php b/app/code/Magento/GraphQl/Model/ResolverInterface.php deleted file mode 100644 index c6ea2d0e2a2e2..0000000000000 --- a/app/code/Magento/GraphQl/Model/ResolverInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\GraphQl\Model; - -/** - * Data retriever for field with arguments used in a GraphQL resolver when a query is processed - */ -interface ResolverInterface -{ - /** - * Parse arguments of a field and convert them to an array structure - * - * @param \Magento\Framework\GraphQl\ArgumentInterface[] $args - * @param \Magento\GraphQl\Model\ResolverContextInterface $context - * @return array|null - * @throws \Magento\Framework\GraphQl\Exception\GraphQlInputException|\Exception - */ - public function resolve(array $args, \Magento\GraphQl\Model\ResolverContextInterface $context); -} diff --git a/app/code/Magento/GraphQl/Model/SchemaGenerator.php b/app/code/Magento/GraphQl/Model/SchemaGenerator.php index 7f1dd151160df..a835995144b16 100644 --- a/app/code/Magento/GraphQl/Model/SchemaGenerator.php +++ b/app/code/Magento/GraphQl/Model/SchemaGenerator.php @@ -8,7 +8,6 @@ use Magento\Framework\GraphQl\Type\SchemaFactory; use Magento\GraphQl\Model\Type\Generator; -use Magento\Framework\GraphQl\ArgumentFactory; use Magento\Framework\GraphQl\TypeFactory; /** @@ -21,11 +20,6 @@ class SchemaGenerator implements SchemaGeneratorInterface */ private $typeGenerator; - /** - * @var ArgumentFactory - */ - private $argumentFactory; - /** * @var TypeFactory */ @@ -38,18 +32,15 @@ class SchemaGenerator implements SchemaGeneratorInterface /** * @param Generator $typeGenerator - * @param ArgumentFactory $argumentFactory * @param TypeFactory $typeFactory * @param SchemaFactory $schemaFactory */ public function __construct( Generator $typeGenerator, - ArgumentFactory $argumentFactory, TypeFactory $typeFactory, SchemaFactory $schemaFactory ) { $this->typeGenerator = $typeGenerator; - $this->argumentFactory = $argumentFactory; $this->typeFactory = $typeFactory; $this->schemaFactory = $schemaFactory; } diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 5887cc958ff2e..6a9a2914368f6 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -8,7 +8,6 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\GraphQl\Model\SchemaGeneratorInterface" type="Magento\GraphQl\Model\SchemaGenerator" /> <preference for="Magento\GraphQl\Model\Type\GeneratorInterface" type="Magento\GraphQl\Model\Type\Generator" /> - <preference for="Magento\Framework\GraphQl\ArgumentInterface" type="Magento\Framework\GraphQl\Argument" /> <preference for="Magento\GraphQl\Model\ResolverContextInterface" type="Magento\GraphQl\Model\ResolverContext" /> <preference for="Magento\Framework\GraphQl\Type\Entity\MapperInterface" type="Magento\Framework\GraphQl\Type\Entity\DefaultMapper"/> <preference for="Magento\Framework\GraphQl\Type\Enum\DataMapperInterface" type="Magento\Framework\GraphQl\Type\Enum\DefaultDataMapper"/> diff --git a/lib/internal/Magento/Framework/GraphQl/Argument.php b/lib/internal/Magento/Framework/GraphQl/Argument.php deleted file mode 100644 index 09b60627ab677..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Argument.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Framework\GraphQl; - -use Magento\Framework\GraphQl\Argument\ArgumentValueInterface; - -/** - * Simple Implementation for interface ArgumentInterface, representing an argument of a field. - */ -class Argument implements ArgumentInterface -{ - /** @var string */ - protected $name; - - /** @var ArgumentValueInterface|ArgumentValueInterface[]|int|int[]|string|string[]|float|float[]|bool */ - protected $value; - - /** - * @param string $name - * @param bool|float|int|ArgumentValueInterface|string $value - */ - public function __construct($name, $value) - { - $this->name = $name; - $this->value = $value; - } - - /** - * {@inheritdoc} - */ - public function getName() : string - { - return $this->name; - } - - /** - * {@inheritdoc} - */ - public function getValue() - { - return $this->value; - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/ArgumentValueInterface.php b/lib/internal/Magento/Framework/GraphQl/Argument/ArgumentValueInterface.php deleted file mode 100644 index 708b72755b7f5..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Argument/ArgumentValueInterface.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Argument; - -/** - * Marker interface to be used for complex values for an argument of a field - */ -interface ArgumentValueInterface -{ - -} diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValue.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValue.php deleted file mode 100644 index cfb4af85a4f58..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValue.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Argument\Filter; - -/** - * Class that holds the find structure is value of connective for easy parsing - */ -class FilterArgumentValue implements FilterArgumentValueInterface -{ - /** - * @var Connective - */ - private $value; - - /** - * @param Connective $value - */ - public function __construct(Connective $value) - { - $this->value = $value; - } - - /** - * {@inheritdoc} - */ - public function getValue() : Connective - { - return $this->value; - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueFactory.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueFactory.php deleted file mode 100644 index 51aaff2cc94ae..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueFactory.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Argument\Filter; - -use Magento\Framework\ObjectManagerInterface; - -/** - * Factory for @see FilterArgumentValue class - */ -class FilterArgumentValueFactory -{ - /** - * @var ObjectManagerInterface - */ - private $objectManager; - - /** - * @param ObjectManagerInterface $objectManager - */ - public function __construct( - ObjectManagerInterface $objectManager - ) { - $this->objectManager = $objectManager; - } - - /** - * Create a FilterArgumentValue class - * - * @param Connective $connective - * @return FilterArgumentValue - */ - public function create(Connective $connective) : FilterArgumentValue - { - return $this->objectManager->create( - FilterArgumentValue::class, - [ - 'value' => $connective, - ] - ); - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueInterface.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueInterface.php deleted file mode 100644 index 51b7e67bc19e7..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/FilterArgumentValueInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Argument\Filter; - -use Magento\Framework\GraphQl\Argument\ArgumentValueInterface; - -/** - * Specific interface for the find argument of a field used for filtering - */ -interface FilterArgumentValueInterface extends ArgumentValueInterface -{ - /** - * Return a structure as connective that defines a find argument used for filtering - * - * @return Connective - */ - public function getValue() : Connective; -} diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/CurrentPage.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/CurrentPage.php index 1de5d7ddb4d49..2ab565e001b3d 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/CurrentPage.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/CurrentPage.php @@ -7,7 +7,6 @@ namespace Magento\Framework\GraphQl\Argument\SearchCriteria\ArgumentApplier; -use Magento\Framework\GraphQl\ArgumentInterface; use Magento\Framework\Api\Search\SearchCriteriaInterface; use Magento\Framework\GraphQl\Argument\SearchCriteria\ArgumentApplierInterface; use Magento\Framework\Phrase; diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Filter.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Filter.php index 5da119bcf2382..ec8d0e1e31a7c 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Filter.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Filter.php @@ -9,11 +9,8 @@ use Magento\Framework\GraphQl\Argument\AstConverterInterface; use Magento\Framework\Api\Search\SearchCriteriaInterface; -use Magento\Framework\GraphQl\Argument\Filter\FilterArgumentValueInterface; -use Magento\Framework\App\ObjectManager; use Magento\Framework\GraphQl\Argument\SearchCriteria\ArgumentApplierInterface; use Magento\Framework\GraphQl\Argument\SearchCriteria\FilterGroupFactory; -use Magento\Framework\Phrase; /** * Class for Filter Argument @@ -48,15 +45,9 @@ public function __construct(AstConverterInterface $astConverter, FilterGroupFact public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument) : SearchCriteriaInterface { $filters = $this->astConverter->convert(\Magento\Catalog\Model\Product::ENTITY, $argument); - if (!empty($filters)) { - $filterGroups = $searchCriteria->getFilterGroups(); - $filterGroups = array_merge($filterGroups, $this->filterGroupFactory->create($filters)); - $searchCriteria->setFilterGroups($filterGroups); - } else { - throw new \Magento\Framework\Exception\RuntimeException( - new Phrase('Argument %1 not of type %2', [$argument->getName(), FilterArgumentValueInterface::class]) - ); - } + $filterGroups = $searchCriteria->getFilterGroups(); + $filterGroups = array_merge($filterGroups, $this->filterGroupFactory->create($filters)); + $searchCriteria->setFilterGroups($filterGroups); return $searchCriteria; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/PageSize.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/PageSize.php index 3f9dad6e7897b..7d7b63d0cd49b 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/PageSize.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/PageSize.php @@ -7,7 +7,6 @@ namespace Magento\Framework\GraphQl\Argument\SearchCriteria\ArgumentApplier; -use Magento\Framework\GraphQl\ArgumentInterface; use Magento\Framework\Api\Search\SearchCriteriaInterface; use Magento\Framework\GraphQl\Argument\SearchCriteria\ArgumentApplierInterface; use Magento\Framework\Phrase; @@ -28,7 +27,7 @@ public function applyArgument(SearchCriteriaInterface $searchCriteria, $argument $searchCriteria->setPageSize($argument); } else { throw new \Magento\Framework\Exception\RuntimeException( - new Phrase('Argument %1 not of type Int', [$argument]) + new Phrase('Argument %1 not of type Int or String', [$argument]) ); } return $searchCriteria; diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Search.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Search.php index 6b21e17981775..3ee0df77bdc48 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Search.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Search.php @@ -11,7 +11,6 @@ use Magento\Framework\Api\Search\FilterGroupBuilder; use Magento\Framework\Api\Search\SearchCriteriaInterface; use Magento\Framework\GraphQl\Argument\SearchCriteria\ArgumentApplierInterface; -use Magento\Framework\GraphQl\ArgumentInterface; class Search implements ArgumentApplierInterface { diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php index 6ae71f241b3f6..a2a4f3fd4f277 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php @@ -7,7 +7,6 @@ namespace Magento\Framework\GraphQl\Argument\SearchCriteria\ArgumentApplier; -use Magento\Framework\GraphQl\ArgumentInterface; use Magento\Framework\Api\Search\SearchCriteriaInterface; use Magento\Framework\Api\SortOrder; use Magento\Framework\Api\SortOrderBuilder; diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierInterface.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierInterface.php index dc31dcffc51bc..a5445ab4f35fb 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplierInterface.php @@ -7,7 +7,6 @@ namespace Magento\Framework\GraphQl\Argument\SearchCriteria; -use Magento\Framework\GraphQl\ArgumentInterface; use Magento\Framework\Api\Search\SearchCriteriaInterface; /** diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/Builder.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/Builder.php index 3a6b7c1747f5a..142a60cfa129d 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/Builder.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/Builder.php @@ -7,7 +7,6 @@ namespace Magento\Framework\GraphQl\Argument\SearchCriteria; -use Magento\Framework\GraphQl\ArgumentInterface; use Magento\Framework\Api\Search\SearchCriteriaInterfaceFactory; use Magento\Framework\Api\Search\SearchCriteriaInterface; diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/FilterGroupFactory.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/FilterGroupFactory.php index 9f92633aa2289..a2683e42f1690 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/FilterGroupFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/FilterGroupFactory.php @@ -12,7 +12,6 @@ use Magento\Framework\GraphQl\Argument\Filter\Operator; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\Search\FilterGroupBuilder; -use Magento\Framework\GraphQl\Argument\Filter\FilterArgumentValueInterface; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\Phrase; use Magento\Framework\Api\Search\FilterGroup; diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/ValueParserInterface.php b/lib/internal/Magento/Framework/GraphQl/Argument/ValueParserInterface.php deleted file mode 100644 index dfb9e1df9ff56..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Argument/ValueParserInterface.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Framework\GraphQl\Argument; - -/** - * Class responsible for transforming an argument value from one array type to a complex or other type - */ -interface ValueParserInterface -{ - /** - * Parse an argument value from an array or scalar to a ArgumentValueInterface - * - * @param array|int|string|float|bool|mixed $value - * @return ArgumentValueInterface|ArgumentValueInterface[]|int|int[]|string|string[]|float|float[]|bool|mixed - */ - public function parse($value); -} diff --git a/lib/internal/Magento/Framework/GraphQl/ArgumentFactory.php b/lib/internal/Magento/Framework/GraphQl/ArgumentFactory.php deleted file mode 100644 index 4d57e313e916c..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/ArgumentFactory.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Framework\GraphQl; - -use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\GraphQl\Argument\ArgumentValueInterface; - -/** - * Creates arguments represented by ArgumentInterface - */ -class ArgumentFactory -{ - /** - * @var ObjectManagerInterface - */ - private $objectManager; - - /** - * @param ObjectManagerInterface $objectManager - */ - public function __construct( - ObjectManagerInterface $objectManager - ) { - $this->objectManager = $objectManager; - } - - /** - * Create a field argument from map - * - * @param string $argumentName - * @param bool|float|int|ArgumentValueInterface|string $argumentValue - * @return ArgumentInterface - */ - public function create($argumentName, $argumentValue) - { - return $this->objectManager->create( - ArgumentInterface::class, - [ - 'name' => $argumentName, - 'value' => $argumentValue - ] - ); - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/ArgumentInterface.php b/lib/internal/Magento/Framework/GraphQl/ArgumentInterface.php deleted file mode 100644 index 9f67c75428ed5..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/ArgumentInterface.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Framework\GraphQl; - -use Magento\Framework\GraphQl\Argument\ArgumentValueInterface; - -/** - * General interface to use for representing an argument of a field. - */ -interface ArgumentInterface -{ - /** - * Return argument name - * - * @return string - */ - public function getName(); - - /** - * Return argument value - * - * @return ArgumentValueInterface|ArgumentValueInterface[]|int|int[]|string|string[]|float|float[]|bool - */ - public function getValue(); -} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/ArgumentConfig.php b/lib/internal/Magento/Framework/GraphQl/Config/ArgumentConfig.php deleted file mode 100644 index f0cbd3501649f..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Config/ArgumentConfig.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Framework\GraphQl\Config; - -use Magento\Framework\GraphQl\Argument\ValueParserInterface; -use Magento\Framework\GraphQl\Argument\ArgumentValueInterface; - -/** - * Data object that holds the configuration for a argument of a field - */ -class ArgumentConfig -{ - /** - * @var ArgumentValueInterface|int|string|float|bool - */ - - private $defaultValue; - - /** - * @var ValueParserInterface - */ - private $valueParser; - - /** - * @param ArgumentValueInterface|int|string|float|bool|null $defaultValue - * @param ValueParserInterface|null $valueParser - */ - public function __construct( - $defaultValue = null, - ValueParserInterface $valueParser = null - ) { - $this->defaultValue = $defaultValue; - $this->valueParser = $valueParser; - } - - /** - * Return the default value - * - * @return ArgumentValueInterface|int|string|float|bool|null $defaultValue - */ - public function getDefaultValue() - { - return $this->defaultValue; - } - - /** - * Return a value parser if one is set - * - * @return ValueParserInterface|null - */ - public function getValueParser() : ?ValueParserInterface - { - return $this->valueParser; - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php index 6e8fa0a347fea..aa6afd11cef80 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php @@ -8,7 +8,6 @@ namespace Magento\Framework\GraphQl\Type\Output\ElementMapper\Formatter; use Magento\Framework\GraphQl\Type\Definition\OutputType; -use Magento\Framework\GraphQl\ArgumentFactory; use Magento\Framework\GraphQl\Config\Data\TypeInterface; use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\Framework\GraphQl\Type\Input\InputMapper; @@ -30,11 +29,6 @@ class Fields implements FormatterInterface */ private $objectManager; - /** - * @var ArgumentFactory - */ - private $argumentFactory; - /** * @var OutputMapper */ @@ -62,7 +56,6 @@ class Fields implements FormatterInterface /** * @param ObjectManagerInterface $objectManager - * @param ArgumentFactory $argumentFactory * @param OutputMapper $outputMapper * @param InputMapper $inputMapper * @param TypeFactory $typeFactory @@ -71,7 +64,6 @@ class Fields implements FormatterInterface */ public function __construct( ObjectManagerInterface $objectManager, - ArgumentFactory $argumentFactory, OutputMapper $outputMapper, InputMapper $inputMapper, TypeFactory $typeFactory, @@ -79,7 +71,6 @@ public function __construct( WrappedTypeProcessor $wrappedTypeProcessor ) { $this->objectManager = $objectManager; - $this->argumentFactory = $argumentFactory; $this->outputMapper = $outputMapper; $this->inputMapper = $inputMapper; $this->typeFactory = $typeFactory; From e1bea8819861fd8e2daa38cabb70ac3ed7aeb67e Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 14 Mar 2018 15:07:25 -0500 Subject: [PATCH 076/668] MAGETWO-89091: CE edition - Update composer dependencies - fix count() issue --- lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php index 97377c94ca91a..4001433b6fe5d 100644 --- a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php +++ b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php @@ -2013,7 +2013,7 @@ public function insertArray($table, array $columns, array $data, $strategy = 0) $bind = []; $columnsCount = count($columns); foreach ($data as $row) { - if ($columnsCount != count($row)) { + if (is_array($row) && $columnsCount != count($row)) { throw new \Zend_Db_Exception('Invalid data for insert'); } $values[] = $this->_prepareInsertData($row, $bind); From 5f507001baaf5ff2b863bc5f6f03b0371d187fe8 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 14 Mar 2018 16:41:18 -0500 Subject: [PATCH 077/668] MAGETWO-89031: Make all graphql methods to return strict type - adding strict types to modules --- .../Model/BundleProductTypeResolver.php | 4 ++- .../Products/DataProvider/ProductPlugin.php | 7 +++--- .../Product/Formatter/BundleOptions.php | 5 ++-- .../Query/BundleProductPostProcessor.php | 5 ++-- .../Model/CatalogProductTypeResolver.php | 4 ++- .../Model/Config/AttributeReader.php | 2 +- .../Model/CustomizableOptionTypeResolver.php | 4 ++- .../ProductInterfaceTypeResolverComposite.php | 11 ++++---- .../ProductLinkTypeResolverComposite.php | 3 ++- .../Model/ProductLinksTypeResolver.php | 4 ++- .../Model/Resolver/Products.php | 1 + .../Products/DataProvider/Product.php | 14 +++-------- .../Product/Formatter/BaseModelData.php | 3 ++- .../Product/Formatter/CustomAttributes.php | 3 ++- .../Product/Formatter/EntityIdToId.php | 3 ++- .../Product/Formatter/MediaGalleryEntries.php | 3 ++- .../Product/Formatter/NewFromTo.php | 3 ++- .../Product/Formatter/Options.php | 3 ++- .../DataProvider/Product/Formatter/Price.php | 3 ++- .../Product/Formatter/ProductLinks.php | 3 ++- .../Product/Formatter/TierPrices.php | 3 ++- .../Product/FormatterComposite.php | 3 ++- .../Product/FormatterInterface.php | 3 ++- .../Products/FilterArgument/AstConverter.php | 13 ++-------- .../Model/Resolver/Products/Query/Filter.php | 25 +++---------------- .../Model/Resolver/Products/Query/Search.php | 4 +-- .../Products/SearchCriteria/Helper/Filter.php | 7 +++--- .../Model/Resolver/Products/SearchResult.php | 6 ++--- .../Resolver/Products/SearchResultFactory.php | 3 ++- .../Model/ConfigurableProductTypeResolver.php | 4 ++- .../Products/DataProvider/ProductPlugin.php | 2 +- .../Product/Formatter/ConfigurableOptions.php | 3 ++- .../Model/DownloadableProductTypeResolver.php | 4 ++- .../Product/Formatter/DownloadableOptions.php | 3 ++- .../Model/GroupedProductLinksTypeResolver.php | 4 ++- .../Model/GroupedProductTypeResolver.php | 4 ++- .../Product/Formatter/ProductLinks.php | 3 ++- .../Model/Resolver/Item.php | 22 ++++++++++------ .../Config/Data/TypeResolverInterface.php | 5 ++-- 39 files changed, 110 insertions(+), 99 deletions(-) diff --git a/app/code/Magento/BundleGraphQl/Model/BundleProductTypeResolver.php b/app/code/Magento/BundleGraphQl/Model/BundleProductTypeResolver.php index 527bcf8975310..8ca7b4ccbdd12 100644 --- a/app/code/Magento/BundleGraphQl/Model/BundleProductTypeResolver.php +++ b/app/code/Magento/BundleGraphQl/Model/BundleProductTypeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\BundleGraphQl\Model; @@ -16,10 +17,11 @@ class BundleProductTypeResolver implements TypeResolverInterface /** * {@inheritdoc} */ - public function resolveType(array $data) + public function resolveType(array $data) : ?string { if (isset($data['type_id']) && $data['type_id'] == 'bundle') { return 'BundleProduct'; } + return null; } } diff --git a/app/code/Magento/BundleGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php b/app/code/Magento/BundleGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php index 690c4fd848e55..592897f323511 100644 --- a/app/code/Magento/BundleGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php +++ b/app/code/Magento/BundleGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\BundleGraphQl\Model\Plugin\Model\Resolver\Products\DataProvider; @@ -82,7 +83,7 @@ public function __construct( * @return SearchResultsInterface * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterGetList(Product $subject, SearchResultsInterface $result) + public function afterGetList(Product $subject, SearchResultsInterface $result) : SearchResultsInterface { $products = []; $productList = $result->getItems(); @@ -121,7 +122,7 @@ public function afterGetList(Product $subject, SearchResultsInterface $result) * @param \Magento\Catalog\Model\Product[] $products * @return array */ - private function getOptionsCollectionByStoreId(array $products) + private function getOptionsCollectionByStoreId(array $products) : array { /** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionsCollection */ $optionsCollection = $this->bundleOption->create()->getResourceCollection(); @@ -179,7 +180,7 @@ private function getOptionsCollectionByStoreId(array $products) * @param array $optionsMap * @return array */ - private function hydrateLinks(array $optionsMap) + private function hydrateLinks(array $optionsMap) : array { $parentIds = []; $optionIds = []; diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BundleOptions.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BundleOptions.php index 92b92c51ab0ad..c2f50d3175dc2 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BundleOptions.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BundleOptions.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\BundleGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; @@ -36,7 +37,7 @@ public function __construct(EnumLookup $enumLookup) * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) + public function format(Product $product, array $productData = []) : array { if ($product->getTypeId() === Bundle::TYPE_CODE) { $productData = $this->formatBundleAttributes($productData); @@ -54,7 +55,7 @@ public function format(Product $product, array $productData = []) * @return array * @throws RuntimeException */ - private function formatBundleAttributes(array $product) + private function formatBundleAttributes(array $product) : array { if (isset($product['price_view'])) { $product['price_view'] diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php index 4a2041f3e65b8..90a28f060ec57 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\BundleGraphQl\Model\Resolver\Products\Query; @@ -101,7 +102,7 @@ public function process(array $resultData) : array 'is_default' => (bool)$link->getIsDefault(), 'price_type' => $this->enumLookup->getEnumValueFromField( 'PriceTypeEnum', - $link->getPriceType() + (string)$link->getPriceType() ) ?: 'DYNAMIC', 'can_change_quantity' => $link->getCanChangeQuantity() ]; @@ -127,7 +128,7 @@ public function process(array $resultData) : array * @param array $bundleMap Map of parent skus and their children they contain [$parentSku => [$child1, $child2...]] * @return array */ - private function addChildData(array $childrenProducts, array $resultData, array $bundleMap) + private function addChildData(array $childrenProducts, array $resultData, array $bundleMap) : array { foreach ($childrenProducts as $childProduct) { $childData = $this->formatter->format($childProduct); diff --git a/app/code/Magento/CatalogGraphQl/Model/CatalogProductTypeResolver.php b/app/code/Magento/CatalogGraphQl/Model/CatalogProductTypeResolver.php index 2fe2b18b19a67..2f3d2903ea0ca 100644 --- a/app/code/Magento/CatalogGraphQl/Model/CatalogProductTypeResolver.php +++ b/app/code/Magento/CatalogGraphQl/Model/CatalogProductTypeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model; @@ -16,7 +17,7 @@ class CatalogProductTypeResolver implements TypeResolverInterface /** * {@inheritdoc} */ - public function resolveType(array $data) + public function resolveType(array $data) : ?string { if (isset($data['type_id'])) { if ($data['type_id'] == 'simple') { @@ -25,5 +26,6 @@ public function resolveType(array $data) return 'VirtualProduct'; } } + return null; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Config/AttributeReader.php b/app/code/Magento/CatalogGraphQl/Model/Config/AttributeReader.php index d940aff6a6ffb..df820e38615e7 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Config/AttributeReader.php +++ b/app/code/Magento/CatalogGraphQl/Model/Config/AttributeReader.php @@ -57,7 +57,7 @@ public function __construct( * @throws GraphQlInputException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function read($scope = null) + public function read($scope = null) : array { $targetStructures = $this->mapper->getMappedTypes(\Magento\Catalog\Model\Product::ENTITY); $config =[]; diff --git a/app/code/Magento/CatalogGraphQl/Model/CustomizableOptionTypeResolver.php b/app/code/Magento/CatalogGraphQl/Model/CustomizableOptionTypeResolver.php index ea8ea203c7f65..4f0e0a96d3b54 100644 --- a/app/code/Magento/CatalogGraphQl/Model/CustomizableOptionTypeResolver.php +++ b/app/code/Magento/CatalogGraphQl/Model/CustomizableOptionTypeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model; @@ -32,11 +33,12 @@ public function __construct(MapperInterface $mapper) /** * {@inheritDoc} */ - public function resolveType(array $data) + public function resolveType(array $data) : ?string { $map = $this->mapper->getMappedTypes(self::ENTITY_TYPE); if (isset($map[$data['type']])) { return $map[$data['type']]; } + return null; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/ProductInterfaceTypeResolverComposite.php b/app/code/Magento/CatalogGraphQl/Model/ProductInterfaceTypeResolverComposite.php index 22cd279ff0c3d..0d2a5b56d0302 100644 --- a/app/code/Magento/CatalogGraphQl/Model/ProductInterfaceTypeResolverComposite.php +++ b/app/code/Magento/CatalogGraphQl/Model/ProductInterfaceTypeResolverComposite.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model; @@ -31,7 +32,7 @@ public function __construct(array $productTypeNameResolvers = []) * {@inheritdoc} * @throws GraphQlInputException */ - public function resolveType(array $data) + public function resolveType(array $data) : ?string { $resolvedType = null; @@ -47,10 +48,8 @@ public function resolveType(array $data) } } - if (!$resolvedType) { - throw new GraphQlInputException( - __('Concrete type for %1 not implemented', ['ProductInterface']) - ); - } + throw new GraphQlInputException( + __('Concrete type for %1 not implemented', ['ProductInterface']) + ); } } diff --git a/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php b/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php index 70e0fb6804b10..936766d232b01 100644 --- a/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php +++ b/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model; @@ -31,7 +32,7 @@ public function __construct(array $productLinksTypeNameResolvers = []) * {@inheritdoc} * @throws GraphQlInputException */ - public function resolveType(array $data) + public function resolveType(array $data) : ?string { $resolvedType = null; diff --git a/app/code/Magento/CatalogGraphQl/Model/ProductLinksTypeResolver.php b/app/code/Magento/CatalogGraphQl/Model/ProductLinksTypeResolver.php index 1dee8b0d8b6ff..45845c6882713 100644 --- a/app/code/Magento/CatalogGraphQl/Model/ProductLinksTypeResolver.php +++ b/app/code/Magento/CatalogGraphQl/Model/ProductLinksTypeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model; @@ -21,7 +22,7 @@ class ProductLinksTypeResolver implements TypeResolverInterface /** * {@inheritdoc} */ - public function resolveType(array $data) + public function resolveType(array $data) : ?string { if (isset($data['link_type'])) { $linkType = $data['link_type']; @@ -29,5 +30,6 @@ public function resolveType(array $data) return 'ProductLinks'; } } + return null; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php index 2f5c38f28102d..b88e56ec6d9b6 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php index 7604a4f4acfc2..6d508b9ec1413 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php @@ -3,22 +3,16 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider; -use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Catalog\Model\Product\Option; -use Magento\Catalog\Model\Product\TierPrice; use Magento\Framework\Api\SearchCriteriaInterface; -use Magento\Framework\Data\SearchResultInterface; -use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\Serialize\SerializerInterface; -use Magento\Framework\Webapi\ServiceOutputProcessor; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Catalog\Api\Data\ProductSearchResultsInterfaceFactory; -use Magento\GraphQl\Model\EntityAttributeList; +use Magento\Framework\Api\SearchResultsInterface; /** * Product field data provider, used for GraphQL resolver processing. @@ -67,9 +61,9 @@ public function __construct( * Gets list of product data with full data set * * @param SearchCriteriaInterface $searchCriteria - * @return SearchResultInterface + * @return SearchResultsInterface */ - public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria) + public function getList(SearchCriteriaInterface $searchCriteria) : SearchResultsInterface { /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */ $collection = $this->collectionFactory->create(); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BaseModelData.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BaseModelData.php index b0b5e97a308c9..8ea689ca99214 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BaseModelData.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BaseModelData.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; @@ -19,7 +20,7 @@ class BaseModelData implements FormatterInterface * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) + public function format(Product $product, array $productData = []) : array { return $product->getData(); } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/CustomAttributes.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/CustomAttributes.php index 04b314139608a..c39b3890da280 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/CustomAttributes.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/CustomAttributes.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; @@ -19,7 +20,7 @@ class CustomAttributes implements FormatterInterface * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) + public function format(Product $product, array $productData = []) : array { foreach ($product->getCustomAttributes() as $customAttribute) { if (!isset($productData[$customAttribute->getAttributeCode()])) { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/EntityIdToId.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/EntityIdToId.php index 72e2e022734f3..83c5db192770f 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/EntityIdToId.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/EntityIdToId.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; @@ -19,7 +20,7 @@ class EntityIdToId implements FormatterInterface * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) + public function format(Product $product, array $productData = []) : array { $productData['id'] = $product->getId(); unset($productData['entity_id']); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/MediaGalleryEntries.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/MediaGalleryEntries.php index 0844d6a7f0d17..572649123a9b2 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/MediaGalleryEntries.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/MediaGalleryEntries.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; @@ -19,7 +20,7 @@ class MediaGalleryEntries implements FormatterInterface * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) + public function format(Product $product, array $productData = []) : array { if (!empty($product->getMediaGalleryEntries())) { foreach ($product->getMediaGalleryEntries() as $key => $entry) { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/NewFromTo.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/NewFromTo.php index 64ca1bbea0e7d..5033893c23d87 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/NewFromTo.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/NewFromTo.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; @@ -19,7 +20,7 @@ class NewFromTo implements FormatterInterface * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) + public function format(Product $product, array $productData = []) : array { if ($product->getData('news_from_date')) { $productData['new_from_date'] = $product->getData('news_from_date'); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Options.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Options.php index 3b9d23460df89..0917335c4535f 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Options.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Options.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; @@ -20,7 +21,7 @@ class Options implements FormatterInterface * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) + public function format(Product $product, array $productData = []) : array { if (!empty($product->getOptions())) { /** @var Option $option */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Price.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Price.php index 6de041a5631c2..f1a0b11caae84 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Price.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Price.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; @@ -43,7 +44,7 @@ public function __construct( * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) + public function format(Product $product, array $productData = []) : array { $priceInfo = $this->priceInfoFactory->create($product); /** @var \Magento\Catalog\Pricing\Price\FinalPriceInterface $finalPrice */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php index 0c8e61e169f13..486c3c66da1da 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; @@ -25,7 +26,7 @@ class ProductLinks implements FormatterInterface * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) + public function format(Product $product, array $productData = []) : array { $productLinks = $product->getProductLinks(); if ($productLinks) { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/TierPrices.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/TierPrices.php index 7b2f6f5a2b68b..b724c63578dc2 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/TierPrices.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/TierPrices.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; @@ -20,7 +21,7 @@ class TierPrices implements FormatterInterface * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) + public function format(Product $product, array $productData = []) : array { $tierPrices = $product->getTierPrices(); if ($tierPrices) { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterComposite.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterComposite.php index 60da664074a9f..66ef1f9287a95 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterComposite.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterComposite.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product; @@ -32,7 +33,7 @@ public function __construct(array $formatterInstances) * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) + public function format(Product $product, array $productData = []) : array { foreach ($this->formatterInstances as $formatterInstance) { $productData = $formatterInstance->format($product, $productData); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterInterface.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterInterface.php index 7e09198bb6e23..bff07d508f161 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterInterface.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product; @@ -20,5 +21,5 @@ interface FormatterInterface * @param array $productData * @return array */ - public function format(Product $product, array $productData = []); + public function format(Product $product, array $productData = []) : array; } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php index 03caa76c98a4c..4f380198333f9 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php @@ -10,7 +10,6 @@ use Magento\Framework\GraphQl\Argument\AstConverterInterface; use Magento\Framework\GraphQl\Config\ConfigInterface; use Magento\Framework\GraphQl\Config\Data\Type; -use Magento\GraphQl\Model\EntityAttributeList; use Magento\Framework\GraphQl\Argument\Filter\Clause\ReferenceTypeFactory; use Magento\Framework\GraphQl\Argument\Filter\Clause\ReferenceType; use Magento\Framework\GraphQl\Argument\Filter\ClauseFactory; @@ -38,11 +37,6 @@ class AstConverter implements AstConverterInterface */ private $referenceTypeFactory; - /** - * @var EntityAttributeList - */ - private $entityAttributeList; - /** * @var ConfigInterface */ @@ -52,20 +46,17 @@ class AstConverter implements AstConverterInterface * @param ClauseFactory $clauseFactory * @param ConnectiveFactory $connectiveFactory * @param ReferenceTypeFactory $referenceTypeFactory - * @param EntityAttributeList $entityAttributeList * @param ConfigInterface $config */ public function __construct( ClauseFactory $clauseFactory, ConnectiveFactory $connectiveFactory, ReferenceTypeFactory $referenceTypeFactory, - EntityAttributeList $entityAttributeList, ConfigInterface $config ) { $this->clauseFactory = $clauseFactory; $this->connectiveFactory = $connectiveFactory; $this->referenceTypeFactory = $referenceTypeFactory; - $this->entityAttributeList = $entityAttributeList; $this->config = $config; } @@ -76,7 +67,7 @@ public function __construct( * @param array $arguments * @return array */ - private function getClausesFromAst(ReferenceType $referenceType, array $arguments) + private function getClausesFromAst(ReferenceType $referenceType, array $arguments) : array { $entityInfo = ['attributes' => $this->getCatalogProductFields()]; $attributes = array_keys($entityInfo['attributes']); @@ -116,7 +107,7 @@ private function getClausesFromAst(ReferenceType $referenceType, array $argument * @return array * @throws \LogicException */ - private function getCatalogProductFields() + private function getCatalogProductFields() : array { $productTypeSchema = $this->config->getTypeStructure('SimpleProduct'); if (!$productTypeSchema instanceof Type) { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php index 1f59bd8a2811a..1c05346ab0fe5 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php @@ -3,11 +3,10 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\Query; -use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\GraphQl\Query\PostFetchProcessorInterface; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product; @@ -20,11 +19,6 @@ */ class Filter { - /** - * @var ProductRepositoryInterface - */ - private $productRepository; - /** * @var SearchResultFactory */ @@ -35,11 +29,6 @@ class Filter */ private $productDataProvider; - /** - * @var SearchCriteriaBuilder - */ - private $searchCriteriaBuilder; - /** * @var FormatterInterface */ @@ -51,25 +40,19 @@ class Filter private $postProcessors; /** - * @param ProductRepositoryInterface $productRepository * @param SearchResultFactory $searchResultFactory * @param Product $productDataProvider - * @param SearchCriteriaBuilder $searchCriteriaBuilder * @param FormatterInterface $formatter * @param PostFetchProcessorInterface[] $postProcessors */ public function __construct( - ProductRepositoryInterface $productRepository, SearchResultFactory $searchResultFactory, Product $productDataProvider, - SearchCriteriaBuilder $searchCriteriaBuilder, FormatterInterface $formatter, array $postProcessors = [] ) { - $this->productRepository = $productRepository; $this->searchResultFactory = $searchResultFactory; $this->productDataProvider = $productDataProvider; - $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->postProcessors = $postProcessors; $this->formatter = $formatter; } @@ -80,7 +63,7 @@ public function __construct( * @param SearchCriteriaInterface $searchCriteria * @return SearchResult */ - public function getResult(SearchCriteriaInterface $searchCriteria) + public function getResult(SearchCriteriaInterface $searchCriteria) : SearchResult { $realPageSize = $searchCriteria->getPageSize(); $realCurrentPage = $searchCriteria->getCurrentPage(); @@ -106,13 +89,13 @@ public function getResult(SearchCriteriaInterface $searchCriteria) } /** - * Paginates array of Ids pulled back in search based off search criteria and total count. + * Paginate an array of Ids that get pulled back in search based off search criteria and total count. * * @param array $ids * @param SearchCriteriaInterface $searchCriteria * @return int[] */ - private function paginateList(array $ids, SearchCriteriaInterface $searchCriteria) + private function paginateList(array $ids, SearchCriteriaInterface $searchCriteria) : array { $length = $searchCriteria->getPageSize(); // Search starts pages from 0 diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php index 4e7047d2daad7..75db4332d6ae7 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\Query; @@ -61,12 +62,11 @@ public function __construct( * @param SearchCriteriaInterface $searchCriteria * @return SearchResult */ - public function getResult(SearchCriteriaInterface $searchCriteria) + public function getResult(SearchCriteriaInterface $searchCriteria) : SearchResult { $realPageSize = $searchCriteria->getPageSize(); $realCurrentPage = $searchCriteria->getCurrentPage(); // Current page must be set to 0 and page size to max for search to grab all ID's as temporary workaround - // for MAGETWO-85611 $searchCriteria->setPageSize(PHP_INT_MAX); $searchCriteria->setCurrentPage(0); $itemsResults = $this->search->search($searchCriteria); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchCriteria/Helper/Filter.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchCriteria/Helper/Filter.php index 84b9632afc3aa..0757eb033329e 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchCriteria/Helper/Filter.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchCriteria/Helper/Filter.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products\SearchCriteria\Helper; @@ -44,7 +45,7 @@ public function __construct(FilterGroupBuilder $filterGroupBuilder, FilterBuilde * @param string|array $value * @return Item */ - public function generate(string $field, string $condition, $value) + public function generate(string $field, string $condition, $value) : Item { $this->filterBuilder->setField($field); $this->filterBuilder->setConditionType($condition); @@ -60,7 +61,7 @@ public function generate(string $field, string $condition, $value) * @param Item $filter * @return SearchCriteriaInterface */ - public function add(SearchCriteriaInterface $searchCriteria, Item $filter) + public function add(SearchCriteriaInterface $searchCriteria, Item $filter) : SearchCriteriaInterface { $filterGroups = $searchCriteria->getFilterGroups(); $filterGroups[] = $this->filterGroupBuilder->addFilter($filter)->create(); @@ -76,7 +77,7 @@ public function add(SearchCriteriaInterface $searchCriteria, Item $filter) * @param string $filterName * @return SearchCriteriaInterface */ - public function remove(SearchCriteriaInterface $searchCriteria, string $filterName) + public function remove(SearchCriteriaInterface $searchCriteria, string $filterName) : SearchCriteriaInterface { $filterGroups = []; foreach ($searchCriteria->getFilterGroups() as $filterGroup) { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchResult.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchResult.php index c0919d90b21f2..106af18af1279 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchResult.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchResult.php @@ -3,10 +3,10 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products; -use Magento\Catalog\Api\Data\ProductSearchResultsInterface; use Magento\Framework\Api\SearchResultsInterface; /** @@ -39,7 +39,7 @@ public function __construct(int $totalCount, array $productsSearchResult) * * @return int */ - public function getTotalCount() + public function getTotalCount() : int { return $this->totalCount; } @@ -49,7 +49,7 @@ public function getTotalCount() * * @return array */ - public function getProductsSearchResult() + public function getProductsSearchResult() : array { return $this->productsSearchResult; } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchResultFactory.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchResultFactory.php index fa2a0e3473a19..120f6ce69fc00 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchResultFactory.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchResultFactory.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver\Products; @@ -33,7 +34,7 @@ public function __construct(ObjectManagerInterface $objectManager) * @param array $productsSearchResult * @return SearchResult */ - public function create(int $totalCount, array $productsSearchResult) + public function create(int $totalCount, array $productsSearchResult) : SearchResult { return $this->objectManager->create( SearchResult::class, diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/ConfigurableProductTypeResolver.php b/app/code/Magento/ConfigurableProductGraphQl/Model/ConfigurableProductTypeResolver.php index 191f802187d56..8dfabefebe636 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/ConfigurableProductTypeResolver.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/ConfigurableProductTypeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\ConfigurableProductGraphQl\Model; @@ -16,10 +17,11 @@ class ConfigurableProductTypeResolver implements TypeResolverInterface /** * {@inheritdoc} */ - public function resolveType(array $data) + public function resolveType(array $data) : ?string { if (isset($data['type_id']) && $data['type_id'] == 'configurable') { return 'ConfigurableProduct'; } + return null; } } diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php index fdf5bbc34f85a..3e39379f6eec1 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php @@ -89,7 +89,7 @@ public function __construct( * @return SearchResultsInterface * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterGetList(Product $subject, SearchResultsInterface $result) + public function afterGetList(Product $subject, SearchResultsInterface $result) : SearchResultsInterface { $processConfigurableData = false; /** @var ProductInterface $product */ diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ConfigurableOptions.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ConfigurableOptions.php index 9924e755c774b..d8fb3e8432ed4 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ConfigurableOptions.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ConfigurableOptions.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\ConfigurableProductGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; @@ -33,7 +34,7 @@ public function __construct(Configurable $configurableData) * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) + public function format(Product $product, array $productData = []) : array { if ($product->getTypeId() === Configurable::TYPE_CODE) { $extensionAttributes = $product->getExtensionAttributes(); diff --git a/app/code/Magento/DownloadableGraphQl/Model/DownloadableProductTypeResolver.php b/app/code/Magento/DownloadableGraphQl/Model/DownloadableProductTypeResolver.php index f788d2c5f1a78..2df7f4f3b39a7 100644 --- a/app/code/Magento/DownloadableGraphQl/Model/DownloadableProductTypeResolver.php +++ b/app/code/Magento/DownloadableGraphQl/Model/DownloadableProductTypeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\DownloadableGraphQl\Model; @@ -16,10 +17,11 @@ class DownloadableProductTypeResolver implements TypeResolverInterface /** * {@inheritdoc} */ - public function resolveType(array $data) + public function resolveType(array $data) : ?string { if (isset($data['type_id']) && $data['type_id'] == 'downloadable') { return 'DownloadableProduct'; } + return null; } } diff --git a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/DownloadableOptions.php b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/DownloadableOptions.php index 73836a6c42e3e..1df5abf823805 100644 --- a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/DownloadableOptions.php +++ b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/DownloadableOptions.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\DownloadableGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; @@ -63,7 +64,7 @@ public function __construct( * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) + public function format(Product $product, array $productData = []) : array { if ($product->getTypeId() === Downloadable::TYPE_DOWNLOADABLE) { $samples = $this->sampleCollection->addTitleToResult($product->getStoreId()) diff --git a/app/code/Magento/GroupedProductGraphQl/Model/GroupedProductLinksTypeResolver.php b/app/code/Magento/GroupedProductGraphQl/Model/GroupedProductLinksTypeResolver.php index cb0f66827f3cc..d8c4c4c260274 100644 --- a/app/code/Magento/GroupedProductGraphQl/Model/GroupedProductLinksTypeResolver.php +++ b/app/code/Magento/GroupedProductGraphQl/Model/GroupedProductLinksTypeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\GroupedProductGraphQl\Model; @@ -21,7 +22,7 @@ class GroupedProductLinksTypeResolver implements TypeResolverInterface /** * {@inheritdoc} */ - public function resolveType(array $data) + public function resolveType(array $data) : ?string { if (isset($data['link_type'])) { $linkType = $data['link_type']; @@ -29,5 +30,6 @@ public function resolveType(array $data) return 'GroupedProductLinks'; } } + return null; } } diff --git a/app/code/Magento/GroupedProductGraphQl/Model/GroupedProductTypeResolver.php b/app/code/Magento/GroupedProductGraphQl/Model/GroupedProductTypeResolver.php index 87053da427663..403d2b59c5c23 100644 --- a/app/code/Magento/GroupedProductGraphQl/Model/GroupedProductTypeResolver.php +++ b/app/code/Magento/GroupedProductGraphQl/Model/GroupedProductTypeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\GroupedProductGraphQl\Model; @@ -16,10 +17,11 @@ class GroupedProductTypeResolver implements TypeResolverInterface /** * {@inheritdoc} */ - public function resolveType(array $data) + public function resolveType(array $data) : ?string { if (isset($data['type_id']) && $data['type_id'] == 'grouped') { return 'GroupedProduct'; } + return null; } } diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php index 29e4ad0fff334..c39f2024d1362 100644 --- a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php +++ b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\GroupedProductGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; @@ -23,7 +24,7 @@ class ProductLinks implements FormatterInterface * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) + public function format(Product $product, array $productData = []) : array { $productLinks = $product->getProductLinks(); if ($productLinks && $product->getTypeId() === Grouped::TYPE_CODE) { diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php index 6ad80dbdbdd4b..68299f61fd9ac 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php +++ b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php @@ -7,9 +7,11 @@ namespace Magento\TestModuleGraphQlQuery\Model\Resolver; use Magento\Framework\GraphQl\Query\PostFetchProcessorInterface; -use Magento\GraphQl\Model\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\TestModuleGraphQlQuery\Api\Data\ItemInterface; use Magento\TestModuleGraphQlQuery\Model\Entity\ItemFactory; +use Magento\Framework\GraphQl\Config\Data\Field; +use GraphQL\Type\Definition\ResolveInfo; class Item implements ResolverInterface { @@ -34,15 +36,19 @@ public function __construct(ItemFactory $itemFactory, array $postFetchProcessors } /** - * {@inheritDoc} + * @inheritdoc */ - public function resolve(array $args, \Magento\GraphQl\Model\ResolverContextInterface $context) - { + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ) : ?array { $id = 0; - /** @var \Magento\Framework\GraphQl\ArgumentInterface $arg */ - foreach ($args as $arg) { - if ($arg->getName() === "id") { - $id = (int)$arg->getValue(); + foreach ($args as $key => $argValue) { + if ($key === "id") { + $id = (int)$argValue; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/TypeResolverInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/TypeResolverInterface.php index 4a13dd5eb74a6..eddd6b180f625 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/TypeResolverInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/TypeResolverInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config\Data; @@ -17,8 +18,8 @@ interface TypeResolverInterface * Determine a concrete GraphQL type based off the given data. * * @param array $data - * @return string + * @return string|null * @throws GraphQlInputException */ - public function resolveType(array $data); + public function resolveType(array $data) : ?string; } From d3a1e526cdd3592382a36b3704ce8379c02ab87e Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Wed, 14 Mar 2018 16:43:26 -0500 Subject: [PATCH 078/668] MAGETWO-88934: Bundle products - Fix Collection --- .../Model/ResourceModel/Option/Collection.php | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Bundle/Model/ResourceModel/Option/Collection.php b/app/code/Magento/Bundle/Model/ResourceModel/Option/Collection.php index 4d630331ed0e2..ce2649c57e7dc 100644 --- a/app/code/Magento/Bundle/Model/ResourceModel/Option/Collection.php +++ b/app/code/Magento/Bundle/Model/ResourceModel/Option/Collection.php @@ -101,18 +101,6 @@ public function setProductIdFilter($productId) { $this->productIds[] = $productId; - return $this; - } - - /** - * Add product ids filter to select. - * - * @return $this - */ - protected function _beforeLoad() - { - parent::_beforeLoad(); - $productTable = $this->getTable('catalog_product_entity'); $linkField = $this->getConnection()->getAutoIncrementField($productTable); $this->getSelect()->join( @@ -120,13 +108,25 @@ protected function _beforeLoad() 'cpe.'.$linkField.' = main_table.parent_id', [] )->where( - "cpe.entity_id in (?)", + "cpe.entity_id = (?)", $this->productIds ); return $this; } + /** + * Clear product id's after load to insure valid future usage of collection. + * + * @return $this + */ + protected function _afterLoad() + { + $this->productIds = []; + + return parent::_afterLoad(); + } + /** * Set product link filter * From 4550dfb7e6f45f05cdbe837f996bd9e982352aa8 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Wed, 14 Mar 2018 16:44:50 -0500 Subject: [PATCH 079/668] MAGETWO-88934: Bundle products - Field level resolvers for bundled --- .../Model/Resolver/BundleItemLinks.php | 86 +++++ .../Model/Resolver/BundleItems.php | 86 +++++ .../Model/Resolver/Links/Product.php | 51 +++ .../Product/Formatter/BundleOptions.php | 4 +- .../Query/BundleProductPostProcessor.php | 317 ++++++++++++++++-- app/code/Magento/BundleGraphQl/etc/di.xml | 19 -- .../Magento/BundleGraphQl/etc/graphql.xml | 6 +- .../Product/Formatter/EntityIdToId.php | 20 +- .../Framework/GraphQl/Resolver/Value.php | 15 + 9 files changed, 548 insertions(+), 56 deletions(-) create mode 100644 app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php create mode 100644 app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php create mode 100644 app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php delete mode 100644 app/code/Magento/BundleGraphQl/etc/di.xml create mode 100644 lib/internal/Magento/Framework/GraphQl/Resolver/Value.php diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php new file mode 100644 index 0000000000000..9554f0ca73c20 --- /dev/null +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\BundleGraphQl\Model\Resolver; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Bundle\Model\Selection; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory; +use Magento\Bundle\Model\ResourceModel\Selection\Collection; +use Magento\Framework\GraphQl\Query\EnumLookup; + +/** + * {@inheritdoc} + */ +class BundleItemLinks implements ResolverInterface +{ + /** + * @var CollectionFactory + */ + private $linkCollectionFactory; + + /** + * @var EnumLookup + */ + private $enumLookup; + + /** + * @param CollectionFactory $linkCollectionFactory + * @param EnumLookup $enumLookup + */ + public function __construct(CollectionFactory $linkCollectionFactory, EnumLookup $enumLookup) + { + $this->linkCollectionFactory = $linkCollectionFactory; + $this->enumLookup = $enumLookup; + } + + /** + * @inheritDoc + */ + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) + { + /** @var Collection $linkCollection */ + $linkCollection = $this->linkCollectionFactory->create(); + $linkCollection->setOptionIdsFilter([$value['option_id']]); + $field = 'parent_product_id'; + foreach ($linkCollection->getSelect()->getPart('from') as $tableAlias => $data) { + if ($data['tableName'] == $linkCollection->getTable('catalog_product_bundle_selection')) { + $field = $tableAlias . '.' . $field; + } + } + + $linkCollection->getSelect() + ->where($field . ' = ?', $value['parent_id']); + + $links = []; + /** @var Selection $link */ + foreach ($linkCollection as $link) { + $data = $link->getData(); + $formattedLink = [ + 'price' => $link->getSelectionPriceValue(), + 'position' => $link->getPosition(), + 'id' => $link->getId(), + 'qty' => (int)$link->getSelectionQty(), + 'is_default' => (bool)$link->getIsDefault(), + 'price_type' => $this->enumLookup->getEnumValueFromField( + 'PriceTypeEnum', + $link->getSelectionPriceType() + ) ?: 'DYNAMIC', + 'can_change_quantity' => $link->getSelectionCanChangeQty(), + ]; + $data = array_replace($data, $formattedLink); + $data['label'] = function () use ($data) { + return isset($data['product']) ? $data['product']['name'] : ""; + }; + $links[] = $data; + } + + return $links; + } +} diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php new file mode 100644 index 0000000000000..ff95c906232f1 --- /dev/null +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\BundleGraphQl\Model\Resolver; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Bundle\Model\Product\Type; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Bundle\Model\OptionFactory; +use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; +use Magento\Store\Model\StoreManagerInterface; + +/** + * {@inheritdoc} + */ +class BundleItems implements ResolverInterface +{ + /** + * @var OptionFactory + */ + private $bundleOption; + + /** + * @var JoinProcessorInterface + */ + private $extensionAttributesJoinProcessor; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @param OptionFactory $bundleOption + * @param JoinProcessorInterface $extensionAttributesJoinProcessor + * @param StoreManagerInterface $storeManager + */ + public function __construct( + OptionFactory $bundleOption, + JoinProcessorInterface $extensionAttributesJoinProcessor, + StoreManagerInterface $storeManager + ) { + $this->bundleOption = $bundleOption; + $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; + $this->storeManager = $storeManager; + } + + /** + * Fetch and format bundle option items. + * + * {@inheritDoc} + */ + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) + { + if ($value['type_id'] !== Type::TYPE_CODE) { + return $value; + } + + /** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionsCollection */ + $optionsCollection = $this->bundleOption->create()->getResourceCollection(); + // All products in collection will have same store id. + $optionsCollection->joinValues($this->storeManager->getStore()->getId()); + $optionsCollection->setProductIdFilter($value['id']); + $optionsCollection->setPositionOrder(); + + $this->extensionAttributesJoinProcessor->process($optionsCollection); + if (empty($optionsCollection->getData())) { + return []; + } + + $options = []; + /** @var \Magento\Bundle\Model\Option $option */ + foreach ($optionsCollection as $option) { + $options[$option->getId()] = $option->getData(); + $options[$option->getId()]['title'] + = $option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle(); + $options[$option->getId()]['sku'] = $value['sku']; + } + + return $options; + } +} diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php new file mode 100644 index 0000000000000..4b9fc6c341cdd --- /dev/null +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php @@ -0,0 +1,51 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\BundleGraphQl\Model\Resolver\Links; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; + +/** + * {@inheritdoc} + */ +class Product implements ResolverInterface +{ + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @var FormatterInterface + */ + private $formatter; + + /** + * @param ProductRepositoryInterface $productRepository + * @param FormatterInterface $formatter + */ + public function __construct(ProductRepositoryInterface $productRepository, FormatterInterface $formatter) + { + $this->productRepository = $productRepository; + $this->formatter = $formatter; + } + + /** + * {@inheritDoc} + */ + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) + { + /** @var \Magento\Catalog\Model\Product $product */ + $product = $this->productRepository->get($value['sku']); + $data = $this->formatter->format($product); + + return $data; + } +} diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BundleOptions.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BundleOptions.php index 92b92c51ab0ad..f903e759f466d 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BundleOptions.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BundleOptions.php @@ -40,8 +40,6 @@ public function format(Product $product, array $productData = []) { if ($product->getTypeId() === Bundle::TYPE_CODE) { $productData = $this->formatBundleAttributes($productData); - $extensionAttributes = $product->getExtensionAttributes(); - $productData['bundle_product_options'] = $extensionAttributes->getBundleProductOptions(); } return $productData; @@ -64,7 +62,7 @@ private function formatBundleAttributes(array $product) $product['ship_bundle_items'] = $this->enumLookup->getEnumValueFromField('ShipBundleItemsEnum', $product['shipment_type']); } - if (isset($product['price_view'])) { + if (isset($product['price_type'])) { $product['dynamic_price'] = !(bool)$product['price_type']; } if (isset($product['sku_type'])) { diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php index 4a2041f3e65b8..38928f805d840 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php @@ -6,16 +6,20 @@ namespace Magento\BundleGraphQl\Model\Resolver\Products\Query; +use Magento\Bundle\Api\Data\OptionInterface; use Magento\Bundle\Model\Product\Type as Bundle; use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SearchResultsInterface; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; +use Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory; +use Magento\Bundle\Model\ResourceModel\Selection\Collection; +use Magento\Bundle\Api\Data\LinkInterfaceFactory; use Magento\Bundle\Api\Data\LinkInterface; -use Magento\Bundle\Model\Option; +use Magento\Framework\EntityManager\MetadataPool; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; use Magento\Catalog\Model\ResourceModel\Product as ProductResource; -use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; -use Magento\Framework\GraphQl\Query\EnumLookup; +use Magento\Store\Model\StoreManagerInterface; /** * Retrieves simple product data for child products, and formats children data @@ -23,15 +27,55 @@ class BundleProductPostProcessor implements \Magento\Framework\GraphQl\Query\PostFetchProcessorInterface { /** - * @var SearchCriteriaBuilder + * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface */ - private $searchCriteriaBuilder; + private $extensionAttributesJoinProcessor; + + /** + * @var \Magento\Bundle\Model\OptionFactory + */ + private $bundleOption; + + /** + * @var \Magento\Framework\Api\DataObjectHelper + */ + private $dataObjectHelper; + + /** + * @var \Magento\Bundle\Api\Data\OptionInterfaceFactory + */ + private $optionFactory; + + /** + * @var CollectionFactory + */ + private $linkCollectionFactory; + + /** + * @var LinkInterfaceFactory + */ + private $linkFactory; + + /** + * @var MetadataPool + */ + private $metadataPool; + + /** + * @var string + */ + private $productLinkField = ""; /** * @var Product */ private $productDataProvider; + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + /** * @var ProductResource */ @@ -43,29 +87,50 @@ class BundleProductPostProcessor implements \Magento\Framework\GraphQl\Query\Pos private $formatter; /** - * @var EnumLookup + * @var StoreManagerInterface */ - private $enumLookup; + private $storeManager; /** - * @param SearchCriteriaBuilder $searchCriteriaBuilder + * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor + * @param \Magento\Bundle\Model\OptionFactory $bundleOption + * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper + * @param \Magento\Bundle\Api\Data\OptionInterfaceFactory $optionFactory + * @param CollectionFactory $linkCollectionFactory + * @param LinkInterfaceFactory $linkFactory + * @param MetadataPool $metadataPool * @param Product $productDataProvider + * @param SearchCriteriaBuilder $searchCriteriaBuilder * @param ProductResource $productResource * @param FormatterInterface $formatter - * @param EnumLookup $enumLookup + * @param StoreManagerInterface $storeManager */ public function __construct( - SearchCriteriaBuilder $searchCriteriaBuilder, + \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, + \Magento\Bundle\Model\OptionFactory $bundleOption, + \Magento\Framework\Api\DataObjectHelper $dataObjectHelper, + \Magento\Bundle\Api\Data\OptionInterfaceFactory $optionFactory, + CollectionFactory $linkCollectionFactory, + LinkInterfaceFactory $linkFactory, + MetadataPool $metadataPool, Product $productDataProvider, + SearchCriteriaBuilder $searchCriteriaBuilder, ProductResource $productResource, FormatterInterface $formatter, - EnumLookup $enumLookup + StoreManagerInterface $storeManager ) { - $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; + $this->bundleOption = $bundleOption; + $this->dataObjectHelper = $dataObjectHelper; + $this->optionFactory = $optionFactory; + $this->linkCollectionFactory = $linkCollectionFactory; + $this->linkFactory = $linkFactory; + $this->metadataPool = $metadataPool; $this->productDataProvider = $productDataProvider; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->productResource = $productResource; $this->formatter = $formatter; - $this->enumLookup = $enumLookup; + $this->storeManager = $storeManager; } /** @@ -76,7 +141,58 @@ public function __construct( */ public function process(array $resultData) : array { + $bundleProducts = []; + $definedVars = get_defined_vars(); + foreach ($resultData as $product) { + if ($product['type_id'] === Bundle::TYPE_CODE) { + $bundleProducts[] = $product; + } + } + + if (empty($bundleProducts)) { + return $resultData; + } + + $optionsMap = $this->getBundleOptionsMap($bundleProducts); + + $optionsMap = $this->hydrateLinks($optionsMap); + $childrenSkus = []; + $bundleMap = []; + $linkField = $this->getProductLinkField(); + /** @var OptionInterface[] $optionList */ + foreach ($optionsMap as $parentId => $optionList) { + foreach ($resultData as $key => $product) { + if ((int)$product[$linkField] === (int)$parentId) { + $resultData[$key]['bundle_product_options'] = $optionList; + foreach ($optionList as $option) { + if ($option->getSku()) { + $childrenSkus[] = $option->getSku(); + $bundleMap[$product[ProductInterface::SKU]][] = $option->getSku(); + continue; + } + + foreach ($option->getProductLinks() as $link) { + if ($link->getSku()) { + $childrenSkus[] = $link->getSku(); + $bundleMap[$product[ProductInterface::SKU]][] = $link->getSku(); + } + } + } + } + } + } + + if (empty($childrenSkus)) { + return $resultData; + } + + $this->searchCriteriaBuilder->addFilter(ProductInterface::SKU, $childrenSkus, 'in'); + $childProducts = $this->productDataProvider->getList($this->searchCriteriaBuilder->create()); + $resultData = $this->addChildData($childProducts->getItems(), $resultData, $bundleMap); + + return $resultData; + $bundleMap = []; foreach ($resultData as $productKey => $product) { if (isset($product['type_id']) && $product['type_id'] === Bundle::TYPE_CODE) { @@ -111,12 +227,141 @@ public function process(array $resultData) : array } } } + } - $this->searchCriteriaBuilder->addFilter(ProductInterface::SKU, $childrenSkus, 'in'); - $childProducts = $this->productDataProvider->getList($this->searchCriteriaBuilder->create()); - $resultData = $this->addChildData($childProducts->getItems(), $resultData, $bundleMap); + /** + * Retrieve bundle option collection with each option list assigned to a parent id key. + * + * Output format: [$parentId => [$option1, $option2...], ...] + * + * @param array $bundleProducts + * @return array + */ + private function getBundleOptionsMap(array $bundleProducts) + { + $uniqueKey = $this->getProductLinkField(); + /** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionsCollection */ + $optionsCollection = $this->bundleOption->create()->getResourceCollection(); + // All products in collection will have same store id. + $optionsCollection->joinValues($this->storeManager->getStore()->getId()); + foreach ($bundleProducts as $product) { + $optionsCollection->setProductIdFilter($product[$uniqueKey]); + } + $optionsCollection->setPositionOrder(); - return $resultData; + $this->extensionAttributesJoinProcessor->process($optionsCollection); + if (empty($optionsCollection->getData())) { + return []; + } + + $optionsMap = []; + /** @var \Magento\Bundle\Model\Option $option */ + foreach ($optionsCollection as $option) { + /** @var OptionInterface $optionInterface */ + $optionInterface = $this->optionFactory->create(); + foreach ($bundleProducts as $product) { + if ((int)$product[$uniqueKey] !== (int)$option->getParentId()) { + continue; + } + + $this->dataObjectHelper->populateWithArray( + $optionInterface, + $option->getData(), + \Magento\Bundle\Api\Data\OptionInterface::class + ); + $optionInterface->setOptionId($option->getOptionId()) + ->setTitle($option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle()) + ->setDefaultTitle($option->getDefaultTitle()) + ->setSku($product['sku']); + break; + } + + if ($optionInterface->getOptionId() === null) { + continue; + } + + if (!isset($optionsMap[$option->getParentId()])) { + $optionsMap[(int)$option->getParentId()] = []; + } + + $optionsMap[(int)$option->getParentId()][] = $optionInterface; + } + + return $optionsMap; + } + + /** + * Hydrate links for input options + * + * @param array $optionsMap + * @return array + */ + private function hydrateLinks(array $optionsMap) + { + $parentIds = []; + $optionIds = []; + foreach ($optionsMap as $parentId => $optionList) { + $parentIds[] = $parentId; + /** @var OptionInterface $option */ + foreach ($optionList as $option) { + if (in_array($option->getOptionId(), $optionIds)) { + continue; + } + + $optionsIds = []; + } + } + + /** @var Collection $linkCollection */ + $linkCollection = $this->linkCollectionFactory->create(); + $linkCollection->setOptionIdsFilter($optionsIds); + $field = 'parent_product_id'; + foreach ($linkCollection->getSelect()->getPart('from') as $tableAlias => $data) { + if ($data['tableName'] == $linkCollection->getTable('catalog_product_bundle_selection')) { + $field = $tableAlias . '.' . $field; + } + } + + $linkCollection->getSelect() + ->where($field . ' IN (?)', $parentIds); + + $productLinksMap = []; + + /** @var \Magento\Catalog\Model\Product $selection $link */ + foreach ($linkCollection as $link) { + $selectionPriceType = $link->getSelectionPriceType(); + $selectionPrice = $link->getSelectionPriceValue(); + /** @var LinkInterface $productLink */ + $productLink = $this->linkFactory->create(); + $this->dataObjectHelper->populateWithArray( + $productLink, + $link->getData(), + \Magento\Bundle\Api\Data\LinkInterface::class + ); + $productLink->setIsDefault($link->getIsDefault()) + ->setId($link->getSelectionId()) + ->setQty($link->getSelectionQty()) + ->setCanChangeQuantity($link->getSelectionCanChangeQty()) + ->setPrice($selectionPrice) + ->setPriceType($selectionPriceType); + if (!isset($productLinksMap[$productLink->getOptionId()])) { + $productLinksMap[$productLink->getOptionId()] = []; + } + $productLinksMap[$productLink->getOptionId()][] = $productLink; + } + + foreach ($productLinksMap as $optionId => $productLinkList) { + foreach ($optionsMap as $parentId => $optionsList) { + /** @var OptionInterface $option */ + foreach ($optionsList as $optionKey => $option) { + if ((int)$option->getOptionId() === (int)$optionId) { + $optionsMap[$parentId][$optionKey]->setProductLinks($productLinkList); + } + } + } + } + + return $optionsMap; } /** @@ -139,20 +384,34 @@ private function addChildData(array $childrenProducts, array $resultData, array foreach ($categoryLinks as $position => $categoryLink) { $childData['category_links'][] = ['position' => $position, 'category_id' => $categoryLink]; } - foreach ($item['items'] as $itemKey => $bundleItem) { - foreach (array_keys($bundleItem['options']) as $optionKey) { - if ($childData['sku'] === $optionKey) { - $resultData[$productKey]['items'][$itemKey]['options'][$optionKey]['product'] - = $childData; - $resultData[$productKey]['items'][$itemKey]['options'][$optionKey]['label'] - = $childData['name']; - } - } - } +// foreach ($item['bundle_product_options'] as $itemKey => $bundleItem) { +// foreach (array_keys($bundleItem['options']) as $optionKey) { +// if ($childData['sku'] === $optionKey) { +// $resultData[$productKey]['items'][$itemKey]['options'][$optionKey]['product'] +// = $childData; +// $resultData[$productKey]['items'][$itemKey]['options'][$optionKey]['label'] +// = $childData['name']; +// } +// } +// } } } } return $resultData; } + + /** + * Get link field name for unique product identifier. + * + * @return string + */ + private function getProductLinkField() + { + if (empty($this->productLinkField)) { + $this->productLinkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); + } + + return $this->productLinkField; + } } diff --git a/app/code/Magento/BundleGraphQl/etc/di.xml b/app/code/Magento/BundleGraphQl/etc/di.xml deleted file mode 100644 index 8629ed28c3ce2..0000000000000 --- a/app/code/Magento/BundleGraphQl/etc/di.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product"> - <plugin name="add_bundle_data" type="Magento\BundleGraphQl\Model\Plugin\Model\Resolver\Products\DataProvider\ProductPlugin"/> - </type> - <type name="Magento\CatalogGraphQl\Model\Resolver\Products\Query\Filter"> - <arguments> - <argument name="postProcessors" xsi:type="array"> - <item name="bundle_processor" xsi:type="object">Magento\BundleGraphQl\Model\Resolver\Products\Query\BundleProductPostProcessor</item> - </argument> - </arguments> - </type> -</config> diff --git a/app/code/Magento/BundleGraphQl/etc/graphql.xml b/app/code/Magento/BundleGraphQl/etc/graphql.xml index 531bec37ba8e7..3cd2dfd722bc8 100644 --- a/app/code/Magento/BundleGraphQl/etc/graphql.xml +++ b/app/code/Magento/BundleGraphQl/etc/graphql.xml @@ -13,7 +13,7 @@ <field xsi:type="ScalarOutputField" name="dynamic_sku" type="Boolean" description="Indicates whether the bundle product has a dynamic SKU."/> <field xsi:type="ObjectOutputField" name="ship_bundle_items" type="ShipBundleItemsEnum" description="Indicates whether to ship bundle items together or individually."/> <field xsi:type="ScalarOutputField" name="dynamic_weight" type="Boolean" description="Indicates whether the bundle product has a dynamically calculated weight."/> - <field xsi:type="ObjectArrayOutputField" name="items" itemType="BundleItem" description="An array containing information about individual bundle items."/> + <field xsi:type="ObjectArrayOutputField" name="items" itemType="BundleItem" resolver="Magento\BundleGraphQl\Model\Resolver\BundleItems" description="An array containing information about individual bundle items."/> </type> <type xsi:type="OutputType" name="BundleItem"> <field xsi:type="ScalarOutputField" name="option_id" type="Int" description="An ID assigned to each type of item in a bundle product."/> @@ -22,7 +22,7 @@ <field xsi:type="ScalarOutputField" name="type" type="String" description="The input type that the customer uses to select the item. Examples include radio button and checkbox." /> <field xsi:type="ScalarOutputField" name="position" type="Int" description="The relative position of this item compared to the other bundle items."/> <field xsi:type="ScalarOutputField" name="sku" type="String" description="The SKU of the bundle product"/> - <field xsi:type="ObjectArrayOutputField" name="options" itemType="BundleItemOption" description="An array of additional options for this bundle item"/> + <field xsi:type="ObjectArrayOutputField" name="options" itemType="BundleItemOption" resolver="Magento\BundleGraphQl\Model\Resolver\BundleItemLinks" description="An array of additional options for this bundle item"/> </type> <type xsi:type="OutputType" name="BundleItemOption"> <!-- is product_id same with entity_id and id ?? --> @@ -36,7 +36,7 @@ <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price of the selected option"/> <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="One of FIXED, PERCENT, or DYNAMIC"/> <field xsi:type="ScalarOutputField" name="can_change_quantity" type="Boolean" description="Indicates whether the customer can change the number of items for this option"/> - <field xsi:type="ObjectOutputField" name="product" type="ProductInterface" description="The ProductInterface object, which contains details about this product option"/> + <field xsi:type="ObjectOutputField" name="product" type="ProductInterface" resolver="Magento\BundleGraphQl\Model\Resolver\Links\Product" description="The ProductInterface object, which contains details about this product option"/> </type> <type xsi:type="Enum" name="ShipBundleItemsEnum"> <item name="together">TOGETHER</item> diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/EntityIdToId.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/EntityIdToId.php index 72e2e022734f3..764c1bd1e6e33 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/EntityIdToId.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/EntityIdToId.php @@ -6,14 +6,29 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; +use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Model\Product; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; +use Magento\Framework\EntityManager\MetadataPool; /** * Fixed the id related data in the product data */ class EntityIdToId implements FormatterInterface { + /** + * @var MetadataPool + */ + private $metadataPool; + + /** + * @param MetadataPool $metadataPool + */ + public function __construct(MetadataPool $metadataPool) + { + $this->metadataPool = $metadataPool; + } + /** * Fix entity id data by converting it to an id key * @@ -21,8 +36,9 @@ class EntityIdToId implements FormatterInterface */ public function format(Product $product, array $productData = []) { - $productData['id'] = $product->getId(); - unset($productData['entity_id']); + $productData['id'] = $product->getData( + $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField() + ); return $productData; } diff --git a/lib/internal/Magento/Framework/GraphQl/Resolver/Value.php b/lib/internal/Magento/Framework/GraphQl/Resolver/Value.php new file mode 100644 index 0000000000000..32898acf819cf --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Resolver/Value.php @@ -0,0 +1,15 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Framework\GraphQl\Resolver; + +/** + * Return value for @see ResolverInterface + */ +class Value extends \GraphQL\Deferred +{ + +} From 22ffa30eb4370f5295c86f048414d249fa5100a7 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Wed, 14 Mar 2018 16:45:28 -0500 Subject: [PATCH 080/668] MAGETWO-88934: Bundle products - Alter resolver --- .../Magento/Framework/GraphQl/Resolver/ResolverInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php b/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php index 615bf78781d98..30e4b049cd8b9 100644 --- a/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php @@ -24,7 +24,7 @@ interface ResolverInterface * @param $context * @param ResolveInfo $info * @throws \Exception - * @return array|null + * @return array|null */ public function resolve( Field $field, From b4ebf2d8515b9c2d77a347a355d074fdda99938f Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Wed, 14 Mar 2018 16:46:20 -0500 Subject: [PATCH 081/668] MAGETWO-88934: Bundle products - Fix formatting --- .../Magento/Framework/GraphQl/Resolver/ResolverInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php b/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php index 30e4b049cd8b9..d657a33e5b010 100644 --- a/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php @@ -25,7 +25,7 @@ interface ResolverInterface * @param ResolveInfo $info * @throws \Exception * @return array|null - */ + */ public function resolve( Field $field, array $value = null, From 7c6a3e98d3f0ff72077b942e41e124fba0d1ffd6 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Wed, 14 Mar 2018 16:54:43 -0500 Subject: [PATCH 082/668] MAGETWO-88934: Bundle products --- .../Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php | 2 +- app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php | 2 +- app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php index 9554f0ca73c20..10c468d2e9158 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php @@ -43,7 +43,7 @@ public function __construct(CollectionFactory $linkCollectionFactory, EnumLookup /** * @inheritDoc */ - public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?array { /** @var Collection $linkCollection */ $linkCollection = $this->linkCollectionFactory->create(); diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php index ff95c906232f1..f0d1b60f97892 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php @@ -54,7 +54,7 @@ public function __construct( * * {@inheritDoc} */ - public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?array { if ($value['type_id'] !== Type::TYPE_CODE) { return $value; diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php index 4b9fc6c341cdd..7a42e4d00065d 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php @@ -40,7 +40,7 @@ public function __construct(ProductRepositoryInterface $productRepository, Forma /** * {@inheritDoc} */ - public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?array { /** @var \Magento\Catalog\Model\Product $product */ $product = $this->productRepository->get($value['sku']); From c7466e1502a2c78b432513fbd9fe3da20535326f Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 14 Mar 2018 17:20:16 -0500 Subject: [PATCH 083/668] MAGETWO-89091: CE edition - Update composer dependencies - change magento/zendframework1 to dev-master --- composer.json | 2 +- composer.lock | 25 +++++++++---------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/composer.json b/composer.json index fae96b345633e..155c09e43c8c2 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,7 @@ "composer/composer": "~1.6.0", "magento/composer": "1.3.0.x-dev", "magento/magento-composer-installer": ">=0.1.11", - "magento/zendframework1": "dev-deprecated-7.2-code as 1.14.0", + "magento/zendframework1": "dev-master", "monolog/monolog": "^1.17", "oyejorge/less.php": "~1.7.0", "pelago/emogrifier": "^2.0.0", diff --git a/composer.lock b/composer.lock index a3d495c5216c5..1c8e2f4a0e10e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "713d37577c51e070639ac6ccff118414", - "content-hash": "0e32ec1f156e383fef6f5a64de8c514e", + "hash": "0691c1c5d615906efcb4dd137b9f8202", + "content-hash": "e4dfd4b35590fb10b27c4cfe388385dd", "packages": [ { "name": "braintree/braintree_php", @@ -669,16 +669,16 @@ }, { "name": "magento/zendframework1", - "version": "dev-deprecated-7.2-code", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/magento-engcom/zf1-php-7.2-support.git", - "reference": "1366f3fcca399f80c4b3195b8a0707ee460821c7" + "reference": "df32cb041603119a448d4634f7d545ab85a8f68a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento-engcom/zf1-php-7.2-support/zipball/1366f3fcca399f80c4b3195b8a0707ee460821c7", - "reference": "1366f3fcca399f80c4b3195b8a0707ee460821c7", + "url": "https://api.github.com/repos/magento-engcom/zf1-php-7.2-support/zipball/df32cb041603119a448d4634f7d545ab85a8f68a", + "reference": "df32cb041603119a448d4634f7d545ab85a8f68a", "shasum": "" }, "archive": { @@ -719,10 +719,10 @@ "zf1" ], "support": { - "source": "https://github.com/magento-engcom/zf1-php-7.2-support/tree/deprecated-7.2-code", + "source": "https://github.com/magento-engcom/zf1-php-7.2-support/tree/master", "issues": "https://github.com/magento-engcom/zf1-php-7.2-support/issues" }, - "time": "2018-03-12 19:46:30" + "time": "2018-03-14 21:49:31" }, { "name": "monolog/monolog", @@ -6303,14 +6303,7 @@ "time": "2018-01-29 19:49:41" } ], - "aliases": [ - { - "alias": "1.14.0", - "alias_normalized": "1.14.0.0", - "version": "dev-deprecated-7.2-code", - "package": "magento/zendframework1" - } - ], + "aliases": [], "minimum-stability": "stable", "stability-flags": { "magento/composer": 20, From 4f943f700e7e295b0c605022f62a327d3f4bda7e Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Thu, 15 Mar 2018 10:59:22 -0500 Subject: [PATCH 084/668] MAGETWO-88934: Refactor resolver to return wrapped value object. --- .../Model/Resolver/BundleItemLinks.php | 24 ++++++++++-- .../Model/Resolver/BundleItems.php | 24 +++++++++--- .../Model/Resolver/Links/Product.php | 24 ++++++++++-- .../Model/Resolver/Products.php | 22 +++++++++-- .../Magento/CatalogGraphQl/etc/graphql.xml | 2 +- .../Model/Resolver/Customer.php | 27 ++++++++++--- .../Resolver/CustomAttributeMetadata.php | 16 ++++++-- .../Model/Resolver/UrlRewrite.php | 3 +- .../Model/Resolver/Item.php | 24 ++++++++++-- .../GraphQl/Resolver/ResolverInterface.php | 4 +- .../GraphQl/Resolver/ValueFactory.php | 38 +++++++++++++++++++ 11 files changed, 175 insertions(+), 33 deletions(-) create mode 100644 lib/internal/Magento/Framework/GraphQl/Resolver/ValueFactory.php diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php index 10c468d2e9158..4cfc9f31d119c 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php @@ -14,6 +14,8 @@ use Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory; use Magento\Bundle\Model\ResourceModel\Selection\Collection; use Magento\Framework\GraphQl\Query\EnumLookup; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; /** * {@inheritdoc} @@ -30,20 +32,30 @@ class BundleItemLinks implements ResolverInterface */ private $enumLookup; + /** + * @var ValueFactory + */ + private $valueFactory; + /** * @param CollectionFactory $linkCollectionFactory * @param EnumLookup $enumLookup + * @param ValueFactory $valueFactory */ - public function __construct(CollectionFactory $linkCollectionFactory, EnumLookup $enumLookup) - { + public function __construct( + CollectionFactory $linkCollectionFactory, + EnumLookup $enumLookup, + ValueFactory $valueFactory + ) { $this->linkCollectionFactory = $linkCollectionFactory; $this->enumLookup = $enumLookup; + $this->valueFactory = $valueFactory; } /** * @inheritDoc */ - public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?array + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?Value { /** @var Collection $linkCollection */ $linkCollection = $this->linkCollectionFactory->create(); @@ -81,6 +93,10 @@ public function resolve(Field $field, array $value = null, array $args = null, $ $links[] = $data; } - return $links; + $result = function () use ($links) { + return $links; + }; + + return $this->valueFactory->create($result); } } diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php index f0d1b60f97892..a4edb4e091f39 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php @@ -12,6 +12,8 @@ use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\Bundle\Model\OptionFactory; use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; use Magento\Store\Model\StoreManagerInterface; /** @@ -34,19 +36,27 @@ class BundleItems implements ResolverInterface */ private $storeManager; + /** + * @var ValueFactory + */ + private $valueFactory; + /** * @param OptionFactory $bundleOption * @param JoinProcessorInterface $extensionAttributesJoinProcessor * @param StoreManagerInterface $storeManager + * @param ValueFactory $valueFactory */ public function __construct( OptionFactory $bundleOption, JoinProcessorInterface $extensionAttributesJoinProcessor, - StoreManagerInterface $storeManager + StoreManagerInterface $storeManager, + ValueFactory $valueFactory ) { $this->bundleOption = $bundleOption; $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; $this->storeManager = $storeManager; + $this->valueFactory = $valueFactory; } /** @@ -54,10 +64,10 @@ public function __construct( * * {@inheritDoc} */ - public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?array + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?Value { if ($value['type_id'] !== Type::TYPE_CODE) { - return $value; + return null; } /** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionsCollection */ @@ -69,7 +79,7 @@ public function resolve(Field $field, array $value = null, array $args = null, $ $this->extensionAttributesJoinProcessor->process($optionsCollection); if (empty($optionsCollection->getData())) { - return []; + return null; } $options = []; @@ -81,6 +91,10 @@ public function resolve(Field $field, array $value = null, array $args = null, $ $options[$option->getId()]['sku'] = $value['sku']; } - return $options; + $result = function () use ($options) { + return $options; + }; + + return $this->valueFactory->create($result); } } diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php index 7a42e4d00065d..7d3cf627589c0 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php @@ -11,6 +11,8 @@ use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; /** * {@inheritdoc} @@ -27,25 +29,39 @@ class Product implements ResolverInterface */ private $formatter; + /** + * @var ValueFactory + */ + private $valueFactory; + /** * @param ProductRepositoryInterface $productRepository * @param FormatterInterface $formatter + * @param ValueFactory $valueFactory */ - public function __construct(ProductRepositoryInterface $productRepository, FormatterInterface $formatter) - { + public function __construct( + ProductRepositoryInterface $productRepository, + FormatterInterface $formatter, + ValueFactory $valueFactory + ) { $this->productRepository = $productRepository; $this->formatter = $formatter; + $this->valueFactory = $valueFactory; } /** * {@inheritDoc} */ - public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?array + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?Value { /** @var \Magento\Catalog\Model\Product $product */ $product = $this->productRepository->get($value['sku']); $data = $this->formatter->format($product); - return $data; + $result = function () use ($data) { + return $data; + }; + + return $this->valueFactory->create($result); } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php index b88e56ec6d9b6..bf832ba5830dc 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php @@ -14,6 +14,8 @@ use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Filter; use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Search; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; /** * Products field resolver, used for GraphQL request processing. @@ -35,19 +37,27 @@ class Products implements ResolverInterface */ private $filterQuery; + /** + * @var ValueFactory + */ + private $valueFactory; + /** * @param Builder $searchCriteriaBuilder * @param Search $searchQuery * @param Filter $filterQuery + * @param ValueFactory $valueFactory */ public function __construct( Builder $searchCriteriaBuilder, Search $searchQuery, - Filter $filterQuery + Filter $filterQuery, + ValueFactory $valueFactory ) { $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->searchQuery = $searchQuery; $this->filterQuery = $filterQuery; + $this->valueFactory = $valueFactory; } /** @@ -59,7 +69,7 @@ public function resolve( array $args = null, $context, ResolveInfo $info - ) : ?array { + ) : ?Value { $searchCriteria = $this->searchCriteriaBuilder->build($args); if (!isset($args['search']) && !isset($args['filter'])) { @@ -89,7 +99,7 @@ public function resolve( ); } - return [ + $data = [ 'total_count' => $searchResult->getTotalCount(), 'items' => $searchResult->getProductsSearchResult(), 'page_info' => [ @@ -97,5 +107,11 @@ public function resolve( 'current_page' => $currentPage ] ]; + + $result = function () use ($data) { + return $data; + }; + + return $this->valueFactory->create($result); } } diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql.xml b/app/code/Magento/CatalogGraphQl/etc/graphql.xml index bee66ec84c178..d6fe68a540890 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql.xml @@ -9,7 +9,7 @@ <argument xsi:type="ScalarArgument" name="search" type="String" description="Text to be used in a full text search. If multiple keywords are specified, each keyword is evaluated separately."/> <argument xsi:type="ObjectArgument" name="filter" type="ProductFilterInput" description="Defines which search criteria to use to find the desired results. Each filter defines the field or fields to be searched, the condition type, and the search value."/> <argument xsi:type="ScalarArgument" name="pageSize" type="Int" default="20" description="The maximum number of items to return. If no value is specified, the search returns 20 items."/> - <argument xsi:type="ScalarArgument" name="currentPage" type="Int" default="0" description="Specifies which page of results to return. If no value is specified, the first page is returned. If you specify a value that is greater than the number of available pages, an error is returned."/> + <argument xsi:type="ScalarArgument" name="currentPage" type="Int" default="1" description="Specifies which page of results to return. If no value is specified, the first page is returned. If you specify a value that is greater than the number of available pages, an error is returned."/> <argument xsi:type="ObjectArgument" name="sort" type="ProductSortInput" description="Specifies which field or fields to use for sorting the results. If you specify more than one field, Magento sorts by the first field listed. Then, if any items have the same value, those items will be sorted by the secondary field. The value for each field can be set to either ASC (ascending) or DESC (descending)."/> </field> </type> diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php index 72ded3817c353..21c85375625a5 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php @@ -12,7 +12,10 @@ use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; use Magento\GraphQl\Model\ResolverContextInterface; +use Magento\CustomerGraphQl\Model\Resolver\Customer\CustomerDataProvider; /** * Customers field resolver, used for GraphQL request processing. @@ -20,17 +23,25 @@ class Customer implements ResolverInterface { /** - * @var Customer\CustomerDataProvider + * @var CustomerDataProvider */ private $customerResolver; /** - * @param \Magento\CustomerGraphQl\Model\Resolver\Customer\CustomerDataProvider $customerResolver + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param CustomerDataProvider $customerResolver + * @param ValueFactory $valueFactory */ public function __construct( - \Magento\CustomerGraphQl\Model\Resolver\Customer\CustomerDataProvider $customerResolver + CustomerDataProvider $customerResolver, + ValueFactory $valueFactory ) { $this->customerResolver = $customerResolver; + $this->valueFactory = $valueFactory; } /** @@ -42,7 +53,7 @@ public function resolve( array $args = null, $context, ResolveInfo $info - ) : ?array { + ) : ?Value { /** @var ResolverContextInterface $context */ if ((!$context->getUserId()) || $context->getUserType() == 4) { throw new GraphQlAuthorizationException( @@ -54,9 +65,13 @@ public function resolve( } try { - return $this->customerResolver->getCustomerById($context->getUserId()); + $data = $this->customerResolver->getCustomerById($context->getUserId()); + $result = function () use ($data) { + return $data; + }; + $this->valueFactory->create($result); } catch (NoSuchEntityException $exception) { - return new GraphQlNoSuchEntityException(__('Customer id %1 does not exist.', [$context->getUserId()])); + throw new GraphQlNoSuchEntityException(__('Customer id %1 does not exist.', [$context->getUserId()])); } } } diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php b/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php index 1f3ce3c7b31d8..cd474cfa5b544 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php @@ -14,6 +14,8 @@ use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\EavGraphQl\Model\Resolver\Query\Type; use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; /** * Resolve data for custom attribute metadata requests @@ -25,12 +27,16 @@ class CustomAttributeMetadata implements ResolverInterface */ private $type; + private $valueFactory; + /** * @param Type $type + * @param ValueFactory $valueFactory */ - public function __construct(Type $type) + public function __construct(Type $type, ValueFactory $valueFactory) { $this->type = $type; + $this->valueFactory = $valueFactory; } /** @@ -42,7 +48,7 @@ public function resolve( array $args = null, $context, ResolveInfo $info - ) : ?array { + ) : ?Value { $attributes['items'] = null; $attributeInputs = $args['attributes']; foreach ($attributeInputs as $attribute) { @@ -81,7 +87,11 @@ public function resolve( ]; } - return $attributes; + $result = function () use ($attributes) { + return $attributes; + }; + + return $this->valueFactory->create($result); } /** diff --git a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php index f83f6dd7d1ce2..6ca646e1c789f 100644 --- a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php +++ b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php @@ -9,6 +9,7 @@ use GraphQL\Type\Definition\ResolveInfo; use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; use Magento\UrlRewrite\Model\UrlFinderInterface; use Magento\Store\Model\StoreManagerInterface; @@ -48,7 +49,7 @@ public function resolve( array $args = null, $context, ResolveInfo $info - ) : ?array { + ) : ?Value { if (isset($args['url'])) { $urlRewrite = $this->findCanonicalUrl($args['url']); if ($urlRewrite) { diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php index 68299f61fd9ac..7795c746f35f7 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php +++ b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php @@ -8,6 +8,8 @@ use Magento\Framework\GraphQl\Query\PostFetchProcessorInterface; use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; use Magento\TestModuleGraphQlQuery\Api\Data\ItemInterface; use Magento\TestModuleGraphQlQuery\Model\Entity\ItemFactory; use Magento\Framework\GraphQl\Config\Data\Field; @@ -25,14 +27,24 @@ class Item implements ResolverInterface */ private $postFetchProcessors; + /** + * @var ValueFactory + */ + private $valueFactory; + /** * @param ItemFactory $itemFactory * @param PostFetchProcessorInterface[] $postFetchProcessors + * @param ValueFactory $valueFactory */ - public function __construct(ItemFactory $itemFactory, array $postFetchProcessors = []) - { + public function __construct( + ItemFactory $itemFactory, + ValueFactory $valueFactory, + array $postFetchProcessors = [] + ) { $this->itemFactory = $itemFactory; $this->postFetchProcessors = $postFetchProcessors; + $this->valueFactory = $valueFactory; } /** @@ -44,7 +56,7 @@ public function resolve( array $args = null, $context, ResolveInfo $info - ) : ?array { + ) : ?Value { $id = 0; foreach ($args as $key => $argValue) { if ($key === "id") { @@ -65,6 +77,10 @@ public function resolve( $itemData = $postFetchProcessor->process($itemData); } - return $itemData; + $result = function () use ($itemData) { + return $itemData; + }; + + return $this->valueFactory->create($result); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php b/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php index d657a33e5b010..28bad47803cb7 100644 --- a/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Resolver/ResolverInterface.php @@ -24,7 +24,7 @@ interface ResolverInterface * @param $context * @param ResolveInfo $info * @throws \Exception - * @return array|null + * @return Value|null */ public function resolve( Field $field, @@ -32,5 +32,5 @@ public function resolve( array $args = null, $context, ResolveInfo $info - ) : ?array; + ) : ?Value; } diff --git a/lib/internal/Magento/Framework/GraphQl/Resolver/ValueFactory.php b/lib/internal/Magento/Framework/GraphQl/Resolver/ValueFactory.php new file mode 100644 index 0000000000000..01842143e9bef --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Resolver/ValueFactory.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Framework\GraphQl\Resolver; +use Magento\Framework\ObjectManagerInterface; + +/** + * Create @see Value to return data from passed in callback to GraphQL library + */ +class ValueFactory +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @param ObjectManagerInterface $objectManager + */ + public function __construct(ObjectManagerInterface $objectManager) + { + $this->objectManager = $objectManager; + } + + /** + * Create value with passed in callback that returns data as parameter; + * + * @param callable $callback + * @return Value + */ + public function create(callable $callback) + { + return $this->objectManager->create(Value::class, ['callback' => $callback]); + } +} From 63cbea8fc1fabdb01f99dd40cb4db85039476fbb Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Thu, 15 Mar 2018 11:41:33 -0500 Subject: [PATCH 085/668] MAGETWO-89031: Make all graphql methods to return strict type - adding strict types to remaining modules --- .../Model/Resolver/BundleItemLinks.php | 2 +- .../Model/Resolver/BundleItems.php | 1 + .../Model/Resolver/Links/Product.php | 1 + .../Query/BundleProductPostProcessor.php | 6 ++-- .../ConfigurableProductPostProcessor.php | 3 +- .../Model/Resolver/Customer.php | 3 +- .../Customer/CustomerDataProvider.php | 10 ++++--- .../Product/Formatter/DownloadableOptions.php | 4 +-- .../Resolver/CustomAttributeMetadata.php | 3 +- .../EavGraphQl/Model/Resolver/Query/Type.php | 3 +- .../Magento/GraphQl/Controller/GraphQl.php | 3 +- .../ContentTypeProcessor.php | 1 + .../HttpHeaderProcessor/StoreProcessor.php | 1 + .../GraphQl/Model/EntityAttributeList.php | 7 +++-- .../Magento/GraphQl/Model/ResolverContext.php | 15 +++++----- .../Model/ResolverContextInterface.php | 19 ++++++------ .../Magento/GraphQl/Model/SchemaGenerator.php | 5 ++-- .../Model/SchemaGeneratorInterface.php | 7 +++-- .../Magento/GraphQl/Model/Type/Generator.php | 12 ++------ .../GraphQl/Model/Type/GeneratorInterface.php | 3 +- .../Test/Unit/Model/Config/XsdTest.php | 15 +++++++--- .../Query/GroupedItemsPostProcessor.php | 3 +- .../Model/Resolver/UrlRewrite.php | 29 ++++++++++++++----- .../Api/AllSoapAndRestInterface.php | 4 ++- .../Api/Data/ItemInterface.php | 19 ++++++------ .../Model/AllSoapAndRest.php | 4 ++- .../Model/Entity/Item.php | 19 ++++++------ .../Model/Resolver/Item.php | 1 + .../Model/Resolver/ItemPostProcessor.php | 1 + 29 files changed, 124 insertions(+), 80 deletions(-) diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php index 4cfc9f31d119c..72cb4c7c92083 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php @@ -3,13 +3,13 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\BundleGraphQl\Model\Resolver; use GraphQL\Type\Definition\ResolveInfo; use Magento\Bundle\Model\Selection; use Magento\Framework\GraphQl\Config\Data\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory; use Magento\Bundle\Model\ResourceModel\Selection\Collection; diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php index a4edb4e091f39..aafe75c804eb7 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\BundleGraphQl\Model\Resolver; diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php index 7d3cf627589c0..bc9213535d1c7 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\BundleGraphQl\Model\Resolver\Links; diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php index 218d2c256e9f1..8fca43be65077 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php @@ -238,7 +238,7 @@ public function process(array $resultData) : array * @param array $bundleProducts * @return array */ - private function getBundleOptionsMap(array $bundleProducts) + private function getBundleOptionsMap(array $bundleProducts) : array { $uniqueKey = $this->getProductLinkField(); /** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionsCollection */ @@ -297,7 +297,7 @@ private function getBundleOptionsMap(array $bundleProducts) * @param array $optionsMap * @return array */ - private function hydrateLinks(array $optionsMap) + private function hydrateLinks(array $optionsMap) : array { $parentIds = []; $optionIds = []; @@ -407,7 +407,7 @@ private function addChildData(array $childrenProducts, array $resultData, array * * @return string */ - private function getProductLinkField() + private function getProductLinkField() : string { if (empty($this->productLinkField)) { $this->productLinkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/Query/ConfigurableProductPostProcessor.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/Query/ConfigurableProductPostProcessor.php index 91ee78e74631b..aaeb79d78e0d9 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/Query/ConfigurableProductPostProcessor.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/Query/ConfigurableProductPostProcessor.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\ConfigurableProductGraphQl\Model\Resolver\Products\Query; @@ -91,7 +92,7 @@ public function process(array $resultData) : array * @param array $resultData * @return array */ - private function addChildData(array $childProducts, array $resultData) + private function addChildData(array $childProducts, array $resultData) : array { /** @var \Magento\Catalog\Model\Product $childProduct */ foreach ($childProducts as $childProduct) { diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php index 21c85375625a5..5fc15a53a7241 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CustomerGraphQl\Model\Resolver; @@ -69,7 +70,7 @@ public function resolve( $result = function () use ($data) { return $data; }; - $this->valueFactory->create($result); + return $this->valueFactory->create($result); } catch (NoSuchEntityException $exception) { throw new GraphQlNoSuchEntityException(__('Customer id %1 does not exist.', [$context->getUserId()])); } diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer/CustomerDataProvider.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer/CustomerDataProvider.php index e8c6a7195a73f..b2934b7e95577 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer/CustomerDataProvider.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer/CustomerDataProvider.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CustomerGraphQl\Model\Resolver\Customer; @@ -11,6 +12,7 @@ use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Serialize\SerializerInterface; use Magento\Framework\Webapi\ServiceOutputProcessor; +use Magento\Customer\Api\Data\CustomerInterface; /** * Customer field data provider, used for GraphQL request processing. @@ -54,7 +56,7 @@ public function __construct( * @return array|null * @throws NoSuchEntityException|LocalizedException */ - public function getCustomerById(int $customerId) + public function getCustomerById(int $customerId) : ?array { try { $customerObject = $this->customerRepository->getById($customerId); @@ -68,10 +70,10 @@ public function getCustomerById(int $customerId) /** * Transform single customer data from object to in array format * - * @param \Magento\Customer\Api\Data\CustomerInterface $customerObject - * @return array|null + * @param CustomerInterface $customerObject + * @return array */ - private function processCustomer(\Magento\Customer\Api\Data\CustomerInterface $customerObject) + private function processCustomer(CustomerInterface $customerObject) : array { $customer = $this->serviceOutputProcessor->process( $customerObject, diff --git a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/DownloadableOptions.php b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/DownloadableOptions.php index 1df5abf823805..b4e9c4fff3efe 100644 --- a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/DownloadableOptions.php +++ b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/DownloadableOptions.php @@ -89,7 +89,7 @@ public function format(Product $product, array $productData = []) : array * @param LinkCollection $links * @return array */ - private function formatLinks(LinkCollection $links) + private function formatLinks(LinkCollection $links) : array { $resultData = []; foreach ($links as $linkKey => $link) { @@ -116,7 +116,7 @@ private function formatLinks(LinkCollection $links) * @param Collection $samples * @return array */ - private function formatSamples(Collection $samples) + private function formatSamples(Collection $samples) : array { $resultData = []; foreach ($samples as $sampleKey => $sample) { diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php b/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php index cd474cfa5b544..8d1f84716d8bb 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/CustomAttributeMetadata.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\EavGraphQl\Model\Resolver; @@ -100,7 +101,7 @@ public function resolve( * @param array $attribute * @return GraphQlInputException */ - private function createInputException(array $attribute) + private function createInputException(array $attribute) : GraphQlInputException { $isCodeSet = isset($attribute['attribute_code']); $isEntitySet = isset($attribute['entity_type']); diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php b/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php index ce277cb639ea7..915975fc8e271 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\EavGraphQl\Model\Resolver\Query; @@ -56,7 +57,7 @@ public function __construct( * @return string * @throws GraphQlInputException */ - public function getType(string $attributeCode, string $entityType) + public function getType(string $attributeCode, string $entityType) : string { $type = $this->typeLocator->getType($attributeCode, $entityType); diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index b8bdeabf39fc7..4ad322ebfc81d 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\GraphQl\Controller; @@ -91,7 +92,7 @@ public function __construct( * @param RequestInterface $request * @return ResponseInterface */ - public function dispatch(RequestInterface $request) + public function dispatch(RequestInterface $request) : ResponseInterface { $statusCode = 200; try { diff --git a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php index a75b3e10775b7..f035b41744a28 100644 --- a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php +++ b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\GraphQl\Controller\HttpHeaderProcessor; diff --git a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php index 655e974b4fdf9..e54d22a923c8a 100644 --- a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php +++ b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\GraphQl\Controller\HttpHeaderProcessor; diff --git a/app/code/Magento/GraphQl/Model/EntityAttributeList.php b/app/code/Magento/GraphQl/Model/EntityAttributeList.php index dfb311f8327b7..9bb0d853616d3 100644 --- a/app/code/Magento/GraphQl/Model/EntityAttributeList.php +++ b/app/code/Magento/GraphQl/Model/EntityAttributeList.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\GraphQl\Model; @@ -70,8 +71,10 @@ public function __construct( * @return boolean[] * @throws GraphQlInputException */ - public function getDefaultEntityAttributes(string $entityCode, MetadataServiceInterface $metadataService = null) - { + public function getDefaultEntityAttributes( + string $entityCode, + MetadataServiceInterface $metadataService = null + ) : array { $this->searchCriteriaBuilder->addFilters( [ $this->filterBuilder diff --git a/app/code/Magento/GraphQl/Model/ResolverContext.php b/app/code/Magento/GraphQl/Model/ResolverContext.php index 880fac8e12d8b..7a9f014319ac1 100644 --- a/app/code/Magento/GraphQl/Model/ResolverContext.php +++ b/app/code/Magento/GraphQl/Model/ResolverContext.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\GraphQl\Model; @@ -66,7 +67,7 @@ public function __construct( * * @return \Magento\GraphQl\Model\ResolverContextExtensionInterface||null */ - public function getExtensionAttributes() + public function getExtensionAttributes() : ?\Magento\GraphQl\Model\ResolverContextExtensionInterface { return $this->_getExtensionAttributes(); } @@ -75,18 +76,18 @@ public function getExtensionAttributes() * {@inheritdoc} * * @param \Magento\GraphQl\Model\ResolverContextExtensionInterface $extensionAttributes - * @return $this + * @return ResolverContextInterface */ public function setExtensionAttributes( \Magento\GraphQl\Model\ResolverContextExtensionInterface $extensionAttributes - ) { + ) : ResolverContextInterface { return $this->_setExtensionAttributes($extensionAttributes); } /** * @inheritDoc */ - public function getUserId() + public function getUserId() : int { if (!$this->getData(self::USER_ID)) { $this->setUserId((int) $this->userContext->getUserId()); @@ -97,7 +98,7 @@ public function getUserId() /** * @inheritDoc */ - public function setUserId(int $userId) + public function setUserId(int $userId) : ResolverContextInterface { return $this->setData(self::USER_ID, $userId); } @@ -105,7 +106,7 @@ public function setUserId(int $userId) /** * @inheritDoc */ - public function getUserType() + public function getUserType() : int { if (!$this->getData(self::USER_TYPE_ID)) { $this->setUserType($this->userContext->getUserType()); @@ -116,7 +117,7 @@ public function getUserType() /** * @inheritDoc */ - public function setUserType(int $typeId) + public function setUserType(int $typeId) : ResolverContextInterface { return $this->setData(self::USER_TYPE_ID, $typeId); } diff --git a/app/code/Magento/GraphQl/Model/ResolverContextInterface.php b/app/code/Magento/GraphQl/Model/ResolverContextInterface.php index 53f1406ffcb94..2eb656f6c16f5 100644 --- a/app/code/Magento/GraphQl/Model/ResolverContextInterface.php +++ b/app/code/Magento/GraphQl/Model/ResolverContextInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\GraphQl\Model; @@ -23,7 +24,7 @@ interface ResolverContextInterface extends ExtensibleDataInterface * * @return int */ - public function getUserType(); + public function getUserType() : int; /** * Set type of a user @@ -31,39 +32,39 @@ public function getUserType(); * @see \Magento\Authorization\Model\UserContextInterface for corespondent values * * @param int $typeId - * @return $this + * @return ResolverContextInterface */ - public function setUserType(int $typeId); + public function setUserType(int $typeId) : ResolverContextInterface; /** * Get id of the user * * @return int */ - public function getUserId(); + public function getUserId() : int; /** * Set id of a user * * @param int $userId - * @return $this + * @return ResolverContextInterface */ - public function setUserId(int $userId); + public function setUserId(int $userId) : ResolverContextInterface; /** * Retrieve existing extension attributes object or create a new one. * * @return \Magento\GraphQl\Model\ResolverContextExtensionInterface|null */ - public function getExtensionAttributes(); + public function getExtensionAttributes() : ?\Magento\GraphQl\Model\ResolverContextExtensionInterface; /** * Set an extension attributes object. * * @param \Magento\GraphQl\Model\ResolverContextExtensionInterface $extensionAttributes - * @return $this + * @return ResolverContextInterface */ public function setExtensionAttributes( \Magento\GraphQl\Model\ResolverContextExtensionInterface $extensionAttributes - ); + ) : ResolverContextInterface; } diff --git a/app/code/Magento/GraphQl/Model/SchemaGenerator.php b/app/code/Magento/GraphQl/Model/SchemaGenerator.php index a835995144b16..ae73c5c6dab0a 100644 --- a/app/code/Magento/GraphQl/Model/SchemaGenerator.php +++ b/app/code/Magento/GraphQl/Model/SchemaGenerator.php @@ -3,10 +3,12 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\GraphQl\Model; use Magento\Framework\GraphQl\Type\SchemaFactory; +use Magento\Framework\GraphQl\Type\Schema; use Magento\GraphQl\Model\Type\Generator; use Magento\Framework\GraphQl\TypeFactory; @@ -47,9 +49,8 @@ public function __construct( /** * {@inheritdoc} - * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ - public function generate() + public function generate() : Schema { $schemaConfig = $this->typeGenerator->generateTypes(); diff --git a/app/code/Magento/GraphQl/Model/SchemaGeneratorInterface.php b/app/code/Magento/GraphQl/Model/SchemaGeneratorInterface.php index 9eaac118982c8..d689cf9c31fc2 100644 --- a/app/code/Magento/GraphQl/Model/SchemaGeneratorInterface.php +++ b/app/code/Magento/GraphQl/Model/SchemaGeneratorInterface.php @@ -3,9 +3,12 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\GraphQl\Model; +use Magento\Framework\GraphQl\Type\Schema; + /** * GraphQL schema generator interface. */ @@ -14,7 +17,7 @@ interface SchemaGeneratorInterface /** * Generate GraphQL schema. * - * @return \Magento\Framework\GraphQl\Type\Schema + * @return Schema */ - public function generate(); + public function generate() : Schema; } diff --git a/app/code/Magento/GraphQl/Model/Type/Generator.php b/app/code/Magento/GraphQl/Model/Type/Generator.php index 3d99d98dfaca6..ee64b8be21158 100644 --- a/app/code/Magento/GraphQl/Model/Type/Generator.php +++ b/app/code/Magento/GraphQl/Model/Type/Generator.php @@ -3,10 +3,10 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\GraphQl\Model\Type; -use Magento\Framework\GraphQl\TypeFactory; use Magento\Framework\GraphQl\SchemaProvider; /** @@ -14,32 +14,24 @@ */ class Generator implements GeneratorInterface { - /** - * @var TypeFactory - */ - private $typeFactory; - /** * @var SchemaProvider */ private $schemaProvider; /** - * @param TypeFactory $typeFactory * @param SchemaProvider $schemaProvider */ public function __construct( - TypeFactory $typeFactory, SchemaProvider $schemaProvider ) { - $this->typeFactory = $typeFactory; $this->schemaProvider = $schemaProvider; } /** * {@inheritdoc} */ - public function generateTypes() + public function generateTypes() : array { $types = []; foreach ($this->schemaProvider->getTypes() as $name => $type) { diff --git a/app/code/Magento/GraphQl/Model/Type/GeneratorInterface.php b/app/code/Magento/GraphQl/Model/Type/GeneratorInterface.php index b7806a49cbdbe..fd16152d88150 100644 --- a/app/code/Magento/GraphQl/Model/Type/GeneratorInterface.php +++ b/app/code/Magento/GraphQl/Model/Type/GeneratorInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\GraphQl\Model\Type; @@ -16,5 +17,5 @@ interface GeneratorInterface * * @return array Represented as ['fields' => ['fieldName' => Type, {...}], 'types' => Types[]] */ - public function generateTypes(); + public function generateTypes() : array; } diff --git a/app/code/Magento/GraphQl/Test/Unit/Model/Config/XsdTest.php b/app/code/Magento/GraphQl/Test/Unit/Model/Config/XsdTest.php index 942a03b35852e..673312618a3bc 100644 --- a/app/code/Magento/GraphQl/Test/Unit/Model/Config/XsdTest.php +++ b/app/code/Magento/GraphQl/Test/Unit/Model/Config/XsdTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\GraphQl\Test\Unit\Model\Config; class XsdTest extends \PHPUnit\Framework\TestCase @@ -18,7 +20,7 @@ class XsdTest extends \PHPUnit\Framework\TestCase */ private $xsdValidator; - protected function setUp() + protected function setUp() : void { if (!function_exists('libxml_set_external_entity_loader')) { $this->markTestSkipped('Skipped on HHVM. Will be fixed in MAGETWO-45033'); @@ -31,15 +33,19 @@ protected function setUp() /** * @param string $xmlString * @param array $expectedError + * @return void * @dataProvider schemaCorrectlyIdentifiesInvalidXmlDataProvider */ - public function testSchemaCorrectlyIdentifiesInvalidXml($xmlString, $expectedError) + public function testSchemaCorrectlyIdentifiesInvalidXml($xmlString, $expectedError) : void { $actualError = $this->xsdValidator->validate($this->xsdSchema, $xmlString); $this->assertEquals($expectedError, $actualError); } - public function testSchemaCorrectlyIdentifiesValidXml() + /** + * @return void + */ + public function testSchemaCorrectlyIdentifiesValidXml() : void { $xmlString = file_get_contents(__DIR__ . '/_files/graphql_simple_configurable.xml'); $actualResult = $this->xsdValidator->validate($this->xsdSchema, $xmlString); @@ -48,8 +54,9 @@ public function testSchemaCorrectlyIdentifiesValidXml() /** * Data provider with invalid xml array according to graphql.xsd + * @return array */ - public function schemaCorrectlyIdentifiesInvalidXmlDataProvider() + public function schemaCorrectlyIdentifiesInvalidXmlDataProvider() : array { return include __DIR__ . '/_files/invalidGraphQlXmlArray.php'; } diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php index 7be9e8e4cf6b9..de948b2be1f2c 100644 --- a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php +++ b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\GroupedProductGraphQl\Model\Resolver\Products\Query; @@ -90,7 +91,7 @@ public function process(array $resultData) : array * @param array $resultData * @return array */ - private function addChildData(array $childResults, array $resultData) + private function addChildData(array $childResults, array $resultData) : array { foreach ($childResults as $child) { $childData = $this->formatter->format($child); diff --git a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php index 6ca646e1c789f..14bd158a06164 100644 --- a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php +++ b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\UrlRewriteGraphQl\Model\Resolver; @@ -12,6 +13,7 @@ use Magento\Framework\GraphQl\Resolver\Value; use Magento\UrlRewrite\Model\UrlFinderInterface; use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\GraphQl\Resolver\ValueFactory; /** * UrlRewrite field resolver, used for GraphQL request processing. @@ -28,16 +30,24 @@ class UrlRewrite implements ResolverInterface */ private $storeManager; + /** + * @var ValueFactory + */ + private $valueFactory; + /** * @param UrlFinderInterface $urlFinder * @param StoreManagerInterface $storeManager + * @param ValueFactory $valueFactory */ public function __construct( UrlFinderInterface $urlFinder, - StoreManagerInterface $storeManager + StoreManagerInterface $storeManager, + ValueFactory $valueFactory ) { $this->urlFinder = $urlFinder; $this->storeManager = $storeManager; + $this->valueFactory = $valueFactory; } /** @@ -53,11 +63,16 @@ public function resolve( if (isset($args['url'])) { $urlRewrite = $this->findCanonicalUrl($args['url']); if ($urlRewrite) { - return [ + $urlRewriteReturnArray = [ 'id' => $urlRewrite->getEntityId(), 'canonical_url' => $urlRewrite->getTargetPath(), 'type' => $this->sanitizeType($urlRewrite->getEntityType()) ]; + $result = function () use ($urlRewriteReturnArray) { + return $urlRewriteReturnArray; + }; + + return $this->valueFactory->create($result); } } return null; @@ -69,7 +84,7 @@ public function resolve( * @param string $requestPath * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null */ - private function findCanonicalUrl(string $requestPath) + private function findCanonicalUrl(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite { $urlRewrite = $this->findUrlFromRequestPath($requestPath); if ($urlRewrite && $urlRewrite->getRedirectType() > 0) { @@ -89,7 +104,7 @@ private function findCanonicalUrl(string $requestPath) * @param string $requestPath * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null */ - private function findUrlFromRequestPath(string $requestPath) + private function findUrlFromRequestPath(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite { return $this->urlFinder->findOneByData( [ @@ -105,7 +120,7 @@ private function findUrlFromRequestPath(string $requestPath) * @param string $targetPath * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null */ - private function findUrlFromTargetPath(string $targetPath) + private function findUrlFromTargetPath(string $targetPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite { return $this->urlFinder->findOneByData( [ @@ -119,9 +134,9 @@ private function findUrlFromTargetPath(string $targetPath) * Sanitize the type to fit schema specifications * * @param string $type - * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null + * @return string */ - private function sanitizeType(string $type) + private function sanitizeType(string $type) : string { return strtoupper(str_replace('-', '_', $type)); } diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Api/AllSoapAndRestInterface.php b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Api/AllSoapAndRestInterface.php index cded1c6785889..d62f205277240 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Api/AllSoapAndRestInterface.php +++ b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Api/AllSoapAndRestInterface.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\TestModuleGraphQlQuery\Api; interface AllSoapAndRestInterface @@ -11,5 +13,5 @@ interface AllSoapAndRestInterface * @param int $itemId * @return \Magento\TestModuleGraphQlQuery\Api\Data\ItemInterface */ - public function item($itemId); + public function item($itemId) : \Magento\TestModuleGraphQlQuery\Api\Data\ItemInterface; } diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Api/Data/ItemInterface.php b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Api/Data/ItemInterface.php index 559767b93e53e..95b303205c443 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Api/Data/ItemInterface.php +++ b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Api/Data/ItemInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\TestModuleGraphQlQuery\Api\Data; @@ -15,37 +16,37 @@ interface ItemInterface extends ExtensibleDataInterface /** * @return int */ - public function getItemId(); + public function getItemId() : int; /** * @param int $itemId - * @return $this + * @return ItemInterface */ - public function setItemId($itemId); + public function setItemId($itemId) : ItemInterface; /** * @return string */ - public function getName(); + public function getName() : string; /** * @param string $name - * @return $this + * @return ItemInterface */ - public function setName($name); + public function setName($name) : ItemInterface; /** * @return \Magento\TestModuleGraphQlQuery\Api\Data\ItemExtensionInterface|null */ - public function getExtensionAttributes(); + public function getExtensionAttributes() : ?\Magento\TestModuleGraphQlQuery\Api\Data\ItemExtensionInterface; /** * Set an extension attributes object. * * @param \Magento\TestModuleGraphQlQuery\Api\Data\ItemExtensionInterface $extensionAttributes - * @return $this + * @return ItemInterface */ public function setExtensionAttributes( \Magento\TestModuleGraphQlQuery\Api\Data\ItemExtensionInterface $extensionAttributes - ); + ) : ItemInterface; } diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/AllSoapAndRest.php b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/AllSoapAndRest.php index 2c67ff85f4142..42497008964a3 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/AllSoapAndRest.php +++ b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/AllSoapAndRest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); + namespace Magento\TestModuleGraphQlQuery\Model; use Magento\TestModuleGraphQlQuery\Api\Data\ItemInterfaceFactory; @@ -26,7 +28,7 @@ public function __construct( /** * {@inheritdoc} */ - public function item($itemId) + public function item($itemId) : \Magento\TestModuleGraphQlQuery\Api\Data\ItemInterface { return $this->itemDataFactory->create()->setItemId($itemId)->setName('testProduct1'); } diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Entity/Item.php b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Entity/Item.php index 4c20195692ed3..ec27b53020822 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Entity/Item.php +++ b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Entity/Item.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\TestModuleGraphQlQuery\Model\Entity; @@ -27,16 +28,16 @@ public function __construct(ExtensionAttributesFactory $extensionAttributesFacto /** * @return int */ - public function getItemId() + public function getItemId() : int { return $this->_data['item_id']; } /** * @param int $itemId - * @return $this + * @return ItemInterface */ - public function setItemId($itemId) + public function setItemId($itemId) : ItemInterface { return $this->setData('item_id', $itemId); } @@ -44,21 +45,21 @@ public function setItemId($itemId) /** * @return string */ - public function getName() + public function getName() : string { return $this->_data['name']; } /** * @param string $name - * @return $this + * @return ItemInterface */ - public function setName($name) + public function setName($name) : ItemInterface { return $this->setData('name', $name); } - public function getExtensionAttributes() + public function getExtensionAttributes() : ?\Magento\TestModuleGraphQlQuery\Api\Data\ItemExtensionInterface { $extensionAttributes = $this->_getExtensionAttributes(); if (null === $extensionAttributes) { @@ -71,7 +72,7 @@ public function getExtensionAttributes() public function setExtensionAttributes( \Magento\TestModuleGraphQlQuery\Api\Data\ItemExtensionInterface $extensionAttributes - ) { - $this->_setExtensionAttributes($extensionAttributes); + ) : ItemInterface { + return $this->_setExtensionAttributes($extensionAttributes); } } diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php index 7795c746f35f7..093aa2c88228e 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php +++ b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/Model/Resolver/Item.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\TestModuleGraphQlQuery\Model\Resolver; diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/Model/Resolver/ItemPostProcessor.php b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/Model/Resolver/ItemPostProcessor.php index a619587ac1b44..c4c7439ed748d 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/Model/Resolver/ItemPostProcessor.php +++ b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/Model/Resolver/ItemPostProcessor.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\TestModuleGraphQlQueryExtension\Model\Resolver; From 8a3d9b7031b727a867770c6444d85ec021c5b152 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Thu, 15 Mar 2018 11:45:57 -0500 Subject: [PATCH 086/668] MAGETWO-88934: Add deferred resolution for child link products --- .../Model/Resolver/Links/Product.php | 33 ++--- .../DataProvider/Deferred/Product.php | 128 ++++++++++++++++++ 2 files changed, 141 insertions(+), 20 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php index 7d3cf627589c0..54f8aa5aba1fe 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php @@ -7,9 +7,9 @@ namespace Magento\BundleGraphQl\Model\Resolver\Links; use GraphQL\Type\Definition\ResolveInfo; -use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred\Product as ProductDataProvider; use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\Framework\GraphQl\Resolver\Value; use Magento\Framework\GraphQl\Resolver\ValueFactory; @@ -20,14 +20,9 @@ class Product implements ResolverInterface { /** - * @var ProductRepositoryInterface + * @var ProductDataProvider */ - private $productRepository; - - /** - * @var FormatterInterface - */ - private $formatter; + private $productDataProvider; /** * @var ValueFactory @@ -35,17 +30,14 @@ class Product implements ResolverInterface private $valueFactory; /** - * @param ProductRepositoryInterface $productRepository - * @param FormatterInterface $formatter + * @param ProductDataProvider $productDataProvider * @param ValueFactory $valueFactory */ public function __construct( - ProductRepositoryInterface $productRepository, - FormatterInterface $formatter, + ProductDataProvider $productDataProvider, ValueFactory $valueFactory ) { - $this->productRepository = $productRepository; - $this->formatter = $formatter; + $this->productDataProvider = $productDataProvider; $this->valueFactory = $valueFactory; } @@ -54,12 +46,13 @@ public function __construct( */ public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?Value { - /** @var \Magento\Catalog\Model\Product $product */ - $product = $this->productRepository->get($value['sku']); - $data = $this->formatter->format($product); + if (!isset($value['sku'])) { + throw new GraphQlInputException(__('No child sku found for product link.')); + } + $this->productDataProvider->addProductSku($value['sku']); - $result = function () use ($data) { - return $data; + $result = function () use ($value) { + return $this->productDataProvider->getProductBySku($value['sku']); }; return $this->valueFactory->create($result); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php new file mode 100644 index 0000000000000..e0766319e04f1 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php @@ -0,0 +1,128 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred; + +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product as ProductDataProvider; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; + +/** + * Deferred resolver for product data. + */ +class Product +{ + /** + * @var ProductDataProvider + */ + private $productDataProvider; + + /** + * @var FormatterInterface + */ + private $formatter; + + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + + /** + * @var string[] + */ + private $productSkus = []; + + /** + * @var array + */ + private $productList = []; + + /** + * @param ProductDataProvider $productDataProvider + * @param FormatterInterface $formatter + * @param SearchCriteriaBuilder $searchCriteriaBuilder + */ + public function __construct( + ProductDataProvider $productDataProvider, + FormatterInterface $formatter, + SearchCriteriaBuilder $searchCriteriaBuilder + ) { + $this->productDataProvider = $productDataProvider; + $this->formatter = $formatter; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + } + + /** + * Add product sku to result set at fetch time. + * + * @param string $sku + * @return void + */ + public function addProductSku(string $sku) : void + { + if (!in_array($sku, $this->productSkus)) { + $this->productSkus[] = $sku; + } + } + + /** + * Add product skus to result set at fetch time. + * + * @param array $skus + * @return void + */ + public function addProductSkus(array $skus) : void + { + foreach ($skus as $sku) { + if (in_array($sku, $this->productSkus)) { + continue; + } + + $this->productSkus[] = $sku; + } + } + + /** + * Get product from result set. + * + * @param string $sku + * @return array|null + */ + public function getProductBySku(string $sku) : ?array + { + $products = $this->fetch(); + + if (!isset($products[$sku])) { + return null; + } + + return $products[$sku]; + } + + /** + * Fetch product data and return in array format. Keys for products will be their skus. + * + * @return array + */ + private function fetch() : array + { + if (empty($this->productSkus) || !empty($this->productList)) { + return $this->productList; + } + + $this->searchCriteriaBuilder->addFilter(ProductInterface::SKU, $this->productSkus, 'in'); + $result = $this->productDataProvider->getList($this->searchCriteriaBuilder->create()); + + /** @var \Magento\Catalog\Model\Product $product */ + foreach ($result->getItems() as $product) { + $this->productList[$product->getSku()] = $this->formatter->format($product); + } + + return $this->productList; + } +} From 85eb11856a01eab9b28d46a1e08254fcede7e81a Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Thu, 15 Mar 2018 14:00:21 -0500 Subject: [PATCH 087/668] MAGETWO-88934: Implement deferred functions for Links --- .../Model/Resolver/BundleItemLinks.php | 67 ++------- .../Model/Resolver/Links/Collection.php | 137 ++++++++++++++++++ 2 files changed, 149 insertions(+), 55 deletions(-) create mode 100644 app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php index 72cb4c7c92083..19878a94fa75f 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php @@ -8,12 +8,9 @@ namespace Magento\BundleGraphQl\Model\Resolver; use GraphQL\Type\Definition\ResolveInfo; -use Magento\Bundle\Model\Selection; +use Magento\BundleGraphQl\Model\Resolver\Links\Collection; use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Resolver\ResolverInterface; -use Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory; -use Magento\Bundle\Model\ResourceModel\Selection\Collection; -use Magento\Framework\GraphQl\Query\EnumLookup; use Magento\Framework\GraphQl\Resolver\Value; use Magento\Framework\GraphQl\Resolver\ValueFactory; @@ -23,14 +20,9 @@ class BundleItemLinks implements ResolverInterface { /** - * @var CollectionFactory + * @var Collection */ - private $linkCollectionFactory; - - /** - * @var EnumLookup - */ - private $enumLookup; + private $linkCollection; /** * @var ValueFactory @@ -38,63 +30,28 @@ class BundleItemLinks implements ResolverInterface private $valueFactory; /** - * @param CollectionFactory $linkCollectionFactory - * @param EnumLookup $enumLookup + * @param Collection $linkCollection * @param ValueFactory $valueFactory */ public function __construct( - CollectionFactory $linkCollectionFactory, - EnumLookup $enumLookup, + Collection $linkCollection, ValueFactory $valueFactory ) { - $this->linkCollectionFactory = $linkCollectionFactory; - $this->enumLookup = $enumLookup; + $this->linkCollection = $linkCollection; $this->valueFactory = $valueFactory; } /** - * @inheritDoc + * {@inheritDoc} */ public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?Value { - /** @var Collection $linkCollection */ - $linkCollection = $this->linkCollectionFactory->create(); - $linkCollection->setOptionIdsFilter([$value['option_id']]); - $field = 'parent_product_id'; - foreach ($linkCollection->getSelect()->getPart('from') as $tableAlias => $data) { - if ($data['tableName'] == $linkCollection->getTable('catalog_product_bundle_selection')) { - $field = $tableAlias . '.' . $field; - } + if (!isset($value['option_id']) || !isset($value['parent_id'])) { + return null; } - - $linkCollection->getSelect() - ->where($field . ' = ?', $value['parent_id']); - - $links = []; - /** @var Selection $link */ - foreach ($linkCollection as $link) { - $data = $link->getData(); - $formattedLink = [ - 'price' => $link->getSelectionPriceValue(), - 'position' => $link->getPosition(), - 'id' => $link->getId(), - 'qty' => (int)$link->getSelectionQty(), - 'is_default' => (bool)$link->getIsDefault(), - 'price_type' => $this->enumLookup->getEnumValueFromField( - 'PriceTypeEnum', - $link->getSelectionPriceType() - ) ?: 'DYNAMIC', - 'can_change_quantity' => $link->getSelectionCanChangeQty(), - ]; - $data = array_replace($data, $formattedLink); - $data['label'] = function () use ($data) { - return isset($data['product']) ? $data['product']['name'] : ""; - }; - $links[] = $data; - } - - $result = function () use ($links) { - return $links; + $this->linkCollection->addIdFilters((int)$value['option_id'], (int)$value['parent_id']); + $result = function () use ($value) { + return $this->linkCollection->getLinksForOptionId((int)$value['option_id']); }; return $this->valueFactory->create($result); diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php new file mode 100644 index 0000000000000..e7e6c9f5f7152 --- /dev/null +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php @@ -0,0 +1,137 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\BundleGraphQl\Model\Resolver\Links; + +use Magento\Bundle\Model\Selection; +use Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory; +use Magento\Bundle\Model\ResourceModel\Selection\Collection as LinkCollection; +use Magento\Framework\GraphQl\Query\EnumLookup; + +/** + * Collection to fetch link data at resolution time. + */ +class Collection +{ + /** + * @var CollectionFactory + */ + private $linkCollectionFactory; + + /** + * @var EnumLookup + */ + private $enumLookup; + + /** + * @var int[] + */ + private $optionIds = []; + + /** + * @var int[] + */ + private $parentIds = []; + + /** + * @var array + */ + private $links = []; + + /** + * @param CollectionFactory $linkCollectionFactory + * @param EnumLookup $enumLookup + */ + public function __construct(CollectionFactory $linkCollectionFactory, EnumLookup $enumLookup) + { + $this->linkCollectionFactory = $linkCollectionFactory; + $this->enumLookup = $enumLookup; + } + + /** + * Add option and id filter pair to filter for fetch. + * + * @param int $optionId + * @param int $parentId + * @return void + */ + public function addIdFilters(int $optionId, int $parentId) : void + { + if (!in_array($optionId, $this->optionIds)) { + $this->optionIds[] = $optionId; + } + if (!in_array($parentId, $this->parentIds)) { + $this->parentIds[] = $parentId; + } + } + + /** + * Retrieve links for passed in option id. + * + * @param int $optionId + * @return array|null + */ + public function getLinksForOptionId(int $optionId) : ?array + { + $linksList = $this->fetch(); + + if (!isset($linksList[$optionId])) { + return null; + } + + return $linksList[$optionId]; + } + + /** + * Fetch product data and return in array format. Keys for products will be their option Ids. + * + * @return array + */ + private function fetch() + { + if (empty($this->optionIds) || empty($this->parentIds) || !empty($this->links)) { + return $this->links; + } + + /** @var LinkCollection $linkCollection */ + $linkCollection = $this->linkCollectionFactory->create(); + $linkCollection->setOptionIdsFilter($this->optionIds); + $field = 'parent_product_id'; + foreach ($linkCollection->getSelect()->getPart('from') as $tableAlias => $data) { + if ($data['tableName'] == $linkCollection->getTable('catalog_product_bundle_selection')) { + $field = $tableAlias . '.' . $field; + } + } + + $linkCollection->getSelect() + ->where($field . ' IN (?)', $this->parentIds); + + /** @var Selection $link */ + foreach ($linkCollection as $link) { + $data = $link->getData(); + $formattedLink = [ + 'price' => $link->getSelectionPriceValue(), + 'position' => $link->getPosition(), + 'id' => $link->getId(), + 'qty' => (int)$link->getSelectionQty(), + 'is_default' => (bool)$link->getIsDefault(), + 'price_type' => $this->enumLookup->getEnumValueFromField( + 'PriceTypeEnum', + (string)$link->getSelectionPriceType() + ) ?: 'DYNAMIC', + 'can_change_quantity' => $link->getSelectionCanChangeQty(), + ]; + $data = array_replace($data, $formattedLink); + if (!isset($this->links[$link->getOptionId()])) { + $this->links[$link->getOptionId()] = []; + } + $this->links[$link->getOptionId()][] = $data; + } + + return $this->links; + } +} From cd35a2d46b179de76aa22ee3e04343d5f3105e50 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Thu, 15 Mar 2018 14:31:09 -0500 Subject: [PATCH 088/668] MAGETWO-88934: Implement deferred resolver execution of bundle options --- .../Model/Resolver/BundleItems.php | 57 ++------ .../Model/Resolver/Links/Collection.php | 2 +- .../Model/Resolver/Options/Collection.php | 126 ++++++++++++++++++ 3 files changed, 137 insertions(+), 48 deletions(-) create mode 100644 app/code/Magento/BundleGraphQl/Model/Resolver/Options/Collection.php diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php index aafe75c804eb7..75c2b4d29e486 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php @@ -11,11 +11,9 @@ use Magento\Bundle\Model\Product\Type; use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Resolver\ResolverInterface; -use Magento\Bundle\Model\OptionFactory; -use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; +use Magento\BundleGraphQl\Model\Resolver\Options\Collection; use Magento\Framework\GraphQl\Resolver\Value; use Magento\Framework\GraphQl\Resolver\ValueFactory; -use Magento\Store\Model\StoreManagerInterface; /** * {@inheritdoc} @@ -23,19 +21,9 @@ class BundleItems implements ResolverInterface { /** - * @var OptionFactory + * @var Collection */ - private $bundleOption; - - /** - * @var JoinProcessorInterface - */ - private $extensionAttributesJoinProcessor; - - /** - * @var StoreManagerInterface - */ - private $storeManager; + private $bundleOptionCollection; /** * @var ValueFactory @@ -43,20 +31,14 @@ class BundleItems implements ResolverInterface private $valueFactory; /** - * @param OptionFactory $bundleOption - * @param JoinProcessorInterface $extensionAttributesJoinProcessor - * @param StoreManagerInterface $storeManager + * @param Collection $bundleOptionCollection * @param ValueFactory $valueFactory */ public function __construct( - OptionFactory $bundleOption, - JoinProcessorInterface $extensionAttributesJoinProcessor, - StoreManagerInterface $storeManager, + Collection $bundleOptionCollection, ValueFactory $valueFactory ) { - $this->bundleOption = $bundleOption; - $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; - $this->storeManager = $storeManager; + $this->bundleOptionCollection = $bundleOptionCollection; $this->valueFactory = $valueFactory; } @@ -67,33 +49,14 @@ public function __construct( */ public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?Value { - if ($value['type_id'] !== Type::TYPE_CODE) { + if ($value['type_id'] !== Type::TYPE_CODE || !isset($value['id']) || !isset($value['sku'])) { return null; } - /** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionsCollection */ - $optionsCollection = $this->bundleOption->create()->getResourceCollection(); - // All products in collection will have same store id. - $optionsCollection->joinValues($this->storeManager->getStore()->getId()); - $optionsCollection->setProductIdFilter($value['id']); - $optionsCollection->setPositionOrder(); - - $this->extensionAttributesJoinProcessor->process($optionsCollection); - if (empty($optionsCollection->getData())) { - return null; - } - - $options = []; - /** @var \Magento\Bundle\Model\Option $option */ - foreach ($optionsCollection as $option) { - $options[$option->getId()] = $option->getData(); - $options[$option->getId()]['title'] - = $option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle(); - $options[$option->getId()]['sku'] = $value['sku']; - } + $this->bundleOptionCollection->addParentFilterData((int)$value['id'], $value['sku']); - $result = function () use ($options) { - return $options; + $result = function () use ($value) { + return $this->bundleOptionCollection->getOptionsByParentId((int)$value['id']); }; return $this->valueFactory->create($result); diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php index e7e6c9f5f7152..5acc8582de8b1 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php @@ -87,7 +87,7 @@ public function getLinksForOptionId(int $optionId) : ?array } /** - * Fetch product data and return in array format. Keys for products will be their option Ids. + * Fetch link data and return in array format. Keys for links will be their option Ids. * * @return array */ diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Collection.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Collection.php new file mode 100644 index 0000000000000..11f63f07a126d --- /dev/null +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Collection.php @@ -0,0 +1,126 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + + +namespace Magento\BundleGraphQl\Model\Resolver\Options; + +use Magento\Bundle\Model\OptionFactory; +use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; +use Magento\Store\Model\StoreManagerInterface; + +/** + * Collection to fetch bundle option data at resolution time. + */ +class Collection +{ + /** + * @var OptionFactory + */ + private $bundleOptionFactory; + + /** + * @var JoinProcessorInterface + */ + private $extensionAttributesJoinProcessor; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var string[] + */ + private $skuMap = []; + + /** + * @var array + */ + private $optionMap = []; + + /** + * @param OptionFactory $bundleOptionFactory + * @param JoinProcessorInterface $extensionAttributesJoinProcessor + * @param StoreManagerInterface $storeManager + */ + public function __construct( + OptionFactory $bundleOptionFactory, + JoinProcessorInterface $extensionAttributesJoinProcessor, + StoreManagerInterface $storeManager + ) { + $this->bundleOptionFactory = $bundleOptionFactory; + $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; + $this->storeManager = $storeManager; + } + + /** + * Add parent id/sku pair to use for option filter at fetch time. + * + * @param int $parentId + * @param string $sku + */ + public function addParentFilterData(int $parentId, string $sku) : void + { + $this->skuMap[$parentId] = $sku; + } + + /** + * Fetch data for bundle options and return the options for the given parent id. + * + * @param int $parentId + * @return array|null + */ + public function getOptionsByParentId(int $parentId) : ?array + { + $options = $this->fetch(); + if (!isset($options[$parentId])) { + return null; + } + + return $options[$parentId]; + } + + /** + * Fetch bundle option data and return in array format. Keys for bundle options will be their parent product ids. + * + * @return array + */ + private function fetch() : array + { + if (empty($this->skuMap) || !empty($this->optionMap)) { + return $this->optionMap; + } + + /** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionsCollection */ + $optionsCollection = $this->bundleOptionFactory->create()->getResourceCollection(); + // All products in collection will have same store id. + $optionsCollection->joinValues($this->storeManager->getStore()->getId()); + foreach (array_keys($this->skuMap) as $id) { + $optionsCollection->setProductIdFilter($id); + } + $optionsCollection->setPositionOrder(); + + $this->extensionAttributesJoinProcessor->process($optionsCollection); + if (empty($optionsCollection->getData())) { + return null; + } + + /** @var \Magento\Bundle\Model\Option $option */ + foreach ($optionsCollection as $option) { + if (!isset($this->optionMap[$option->getParentId()])) { + $this->optionMap[$option->getParentId()] = []; + } + $this->optionMap[$option->getParentId()][$option->getId()] = $option->getData(); + $this->optionMap[$option->getParentId()][$option->getId()]['title'] + = $option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle(); + $this->optionMap[$option->getParentId()][$option->getId()]['sku'] + = $this->skuMap[$option->getParentId()]; + } + + return $this->optionMap; + } +} From 270079883db5679fd2ceeef0d35f4f5499fed2a0 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Thu, 15 Mar 2018 14:34:28 -0500 Subject: [PATCH 089/668] MAGETWO-88934: Remove unnecessary bundle performance classes --- .../Products/DataProvider/ProductPlugin.php | 250 ----------- .../Query/BundleProductPostProcessor.php | 418 ------------------ 2 files changed, 668 deletions(-) delete mode 100644 app/code/Magento/BundleGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php delete mode 100644 app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php diff --git a/app/code/Magento/BundleGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php b/app/code/Magento/BundleGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php deleted file mode 100644 index 592897f323511..0000000000000 --- a/app/code/Magento/BundleGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php +++ /dev/null @@ -1,250 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\BundleGraphQl\Model\Plugin\Model\Resolver\Products\DataProvider; - -use Magento\Bundle\Api\Data\OptionInterface; -use Magento\Bundle\Model\Product\Type as Bundle; -use Magento\Framework\Api\SearchResultsInterface; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product; -use Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory; -use Magento\Bundle\Model\ResourceModel\Selection\Collection; -use Magento\Bundle\Api\Data\LinkInterfaceFactory; -use Magento\Bundle\Api\Data\LinkInterface; - -/** - * Fetch bundle product object and set necessary extension attributes for search result - */ -class ProductPlugin -{ - /** - * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface - */ - private $extensionAttributesJoinProcessor; - - /** - * @var \Magento\Bundle\Model\OptionFactory - */ - private $bundleOption; - - /** - * @var \Magento\Framework\Api\DataObjectHelper - */ - private $dataObjectHelper; - - /** - * @var \Magento\Bundle\Api\Data\OptionInterfaceFactory - */ - private $optionFactory; - - /** - * @var CollectionFactory - */ - private $linkCollectionFactory; - - /** - * @var LinkInterfaceFactory - */ - private $linkFactory; - - /** - * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor - * @param \Magento\Bundle\Model\OptionFactory $bundleOption - * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper - * @param \Magento\Bundle\Api\Data\OptionInterfaceFactory $optionFactory - * @param CollectionFactory $linkCollectionFactory - * @param LinkInterfaceFactory $linkFactory - */ - public function __construct( - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, - \Magento\Bundle\Model\OptionFactory $bundleOption, - \Magento\Framework\Api\DataObjectHelper $dataObjectHelper, - \Magento\Bundle\Api\Data\OptionInterfaceFactory $optionFactory, - CollectionFactory $linkCollectionFactory, - LinkInterfaceFactory $linkFactory - ) { - $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; - $this->bundleOption = $bundleOption; - $this->dataObjectHelper = $dataObjectHelper; - $this->optionFactory = $optionFactory; - $this->linkCollectionFactory = $linkCollectionFactory; - $this->linkFactory = $linkFactory; - } - - /** - * Intercept GraphQLCatalog getList, and add any necessary bundle fields - * - * @param Product $subject - * @param SearchResultsInterface $result - * @return SearchResultsInterface - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function afterGetList(Product $subject, SearchResultsInterface $result) : SearchResultsInterface - { - $products = []; - $productList = $result->getItems(); - /** @var \Magento\Catalog\Model\Product $product */ - foreach ($result->getItems() as $product) { - if ($product->getTypeId() === Bundle::TYPE_CODE) { - $products[] = $product; - } - } - - if (empty($products)) { - return $result; - } - - $options = $this->getOptionsCollectionByStoreId($products); - - $options = $this->hydrateLinks($options); - - foreach ($options as $parentId => $optionList) { - foreach ($productList as $product) { - if (!(int)$product->getId() === $parentId) { - continue; - } - $extensionAttributes = $product->getExtensionAttributes(); - $extensionAttributes->setBundleProductOptions($optionList); - $product->setExtensionAttributes($extensionAttributes); - } - } - - return $result; - } - - /** - * Retrieve bundle option collection - * - * @param \Magento\Catalog\Model\Product[] $products - * @return array - */ - private function getOptionsCollectionByStoreId(array $products) : array - { - /** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionsCollection */ - $optionsCollection = $this->bundleOption->create()->getResourceCollection(); - // All products in collection will have same store id. - $optionsCollection->joinValues($products[0]->getStoreId()); - foreach ($products as $product) { - $optionsCollection->setProductIdFilter($product->getEntityId()); - } - $optionsCollection->setPositionOrder(); - - $this->extensionAttributesJoinProcessor->process($optionsCollection); - if (empty($optionsCollection->getData())) { - return []; - } - - $options = []; - /** @var \Magento\Bundle\Model\Option $option */ - foreach ($optionsCollection as $option) { - /** @var OptionInterface $optionInterface */ - $optionInterface = $this->optionFactory->create(); - foreach ($products as $product) { - if ((int)$product->getId() !== (int)$option->getParentId()) { - continue; - } - - $this->dataObjectHelper->populateWithArray( - $optionInterface, - $option->getData(), - \Magento\Bundle\Api\Data\OptionInterface::class - ); - $optionInterface->setOptionId($option->getOptionId()) - ->setTitle($option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle()) - ->setDefaultTitle($option->getDefaultTitle()) - ->setSku($product->getSku()); - break; - } - - if ($optionInterface->getOptionId() === null) { - continue; - } - - if (!isset($options[$option->getParentId()])) { - $options[(int)$option->getParentId()] = []; - } - - $options[(int)$option->getParentId()][] = $optionInterface; - } - - return $options; - } - - /** - * Hydrate links for input options - * - * @param array $optionsMap - * @return array - */ - private function hydrateLinks(array $optionsMap) : array - { - $parentIds = []; - $optionIds = []; - foreach ($optionsMap as $parentId => $optionList) { - $parentIds[] = $parentId; - /** @var OptionInterface $option */ - foreach ($optionList as $option) { - if (in_array($option->getOptionId(), $optionIds)) { - continue; - } - - $optionsIds = []; - } - } - - /** @var Collection $linkCollection */ - $linkCollection = $this->linkCollectionFactory->create(); - $linkCollection->setOptionIdsFilter($optionsIds); - $field = 'parent_product_id'; - foreach ($linkCollection->getSelect()->getPart('from') as $tableAlias => $data) { - if ($data['tableName'] == $linkCollection->getTable('catalog_product_bundle_selection')) { - $field = $tableAlias . '.' . $field; - } - } - - $linkCollection->getSelect() - ->where($field . ' IN (?)', $parentIds); - - $productLinksMap = []; - - /** @var \Magento\Catalog\Model\Product $selection $link */ - foreach ($linkCollection as $link) { - $selectionPriceType = $link->getSelectionPriceType(); - $selectionPrice = $link->getSelectionPriceValue(); - /** @var LinkInterface $productLink */ - $productLink = $this->linkFactory->create(); - $this->dataObjectHelper->populateWithArray( - $productLink, - $link->getData(), - \Magento\Bundle\Api\Data\LinkInterface::class - ); - $productLink->setIsDefault($link->getIsDefault()) - ->setId($link->getSelectionId()) - ->setQty($link->getSelectionQty()) - ->setCanChangeQuantity($link->getSelectionCanChangeQty()) - ->setPrice($selectionPrice) - ->setPriceType($selectionPriceType); - if (!isset($productLinksMap[$productLink->getOptionId()])) { - $productLinksMap[$productLink->getOptionId()] = []; - } - $productLinksMap[$productLink->getOptionId()][] = $productLink; - } - - foreach ($productLinksMap as $optionId => $productLinkList) { - foreach ($optionsMap as $parentId => $optionsList) { - /** @var OptionInterface $option */ - foreach ($optionsList as $optionKey => $option) { - if ((int)$option->getOptionId() === (int)$optionId) { - $optionsMap[$parentId][$optionKey]->setProductLinks($productLinkList); - } - } - } - } - - return $optionsMap; - } -} diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php deleted file mode 100644 index 8fca43be65077..0000000000000 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/Query/BundleProductPostProcessor.php +++ /dev/null @@ -1,418 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\BundleGraphQl\Model\Resolver\Products\Query; - -use Magento\Bundle\Api\Data\OptionInterface; -use Magento\Bundle\Model\Product\Type as Bundle; -use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Framework\Api\SearchResultsInterface; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product; -use Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory; -use Magento\Bundle\Model\ResourceModel\Selection\Collection; -use Magento\Bundle\Api\Data\LinkInterfaceFactory; -use Magento\Bundle\Api\Data\LinkInterface; -use Magento\Framework\EntityManager\MetadataPool; -use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; -use Magento\Catalog\Model\ResourceModel\Product as ProductResource; -use Magento\Store\Model\StoreManagerInterface; - -/** - * Retrieves simple product data for child products, and formats children data - */ -class BundleProductPostProcessor implements \Magento\Framework\GraphQl\Query\PostFetchProcessorInterface -{ - /** - * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface - */ - private $extensionAttributesJoinProcessor; - - /** - * @var \Magento\Bundle\Model\OptionFactory - */ - private $bundleOption; - - /** - * @var \Magento\Framework\Api\DataObjectHelper - */ - private $dataObjectHelper; - - /** - * @var \Magento\Bundle\Api\Data\OptionInterfaceFactory - */ - private $optionFactory; - - /** - * @var CollectionFactory - */ - private $linkCollectionFactory; - - /** - * @var LinkInterfaceFactory - */ - private $linkFactory; - - /** - * @var MetadataPool - */ - private $metadataPool; - - /** - * @var string - */ - private $productLinkField = ""; - - /** - * @var Product - */ - private $productDataProvider; - - /** - * @var SearchCriteriaBuilder - */ - private $searchCriteriaBuilder; - - /** - * @var ProductResource - */ - private $productResource; - - /** - * @var FormatterInterface - */ - private $formatter; - - /** - * @var StoreManagerInterface - */ - private $storeManager; - - /** - * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor - * @param \Magento\Bundle\Model\OptionFactory $bundleOption - * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper - * @param \Magento\Bundle\Api\Data\OptionInterfaceFactory $optionFactory - * @param CollectionFactory $linkCollectionFactory - * @param LinkInterfaceFactory $linkFactory - * @param MetadataPool $metadataPool - * @param Product $productDataProvider - * @param SearchCriteriaBuilder $searchCriteriaBuilder - * @param ProductResource $productResource - * @param FormatterInterface $formatter - * @param StoreManagerInterface $storeManager - */ - public function __construct( - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, - \Magento\Bundle\Model\OptionFactory $bundleOption, - \Magento\Framework\Api\DataObjectHelper $dataObjectHelper, - \Magento\Bundle\Api\Data\OptionInterfaceFactory $optionFactory, - CollectionFactory $linkCollectionFactory, - LinkInterfaceFactory $linkFactory, - MetadataPool $metadataPool, - Product $productDataProvider, - SearchCriteriaBuilder $searchCriteriaBuilder, - ProductResource $productResource, - FormatterInterface $formatter, - StoreManagerInterface $storeManager - ) { - $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; - $this->bundleOption = $bundleOption; - $this->dataObjectHelper = $dataObjectHelper; - $this->optionFactory = $optionFactory; - $this->linkCollectionFactory = $linkCollectionFactory; - $this->linkFactory = $linkFactory; - $this->metadataPool = $metadataPool; - $this->productDataProvider = $productDataProvider; - $this->searchCriteriaBuilder = $searchCriteriaBuilder; - $this->productResource = $productResource; - $this->formatter = $formatter; - $this->storeManager = $storeManager; - } - - /** - * Process all bundle product data, including adding simple product data and formatting relevant attributes. - * - * @param array $resultData - * @return array - */ - public function process(array $resultData) : array - { - $bundleProducts = []; - $definedVars = get_defined_vars(); - foreach ($resultData as $product) { - if ($product['type_id'] === Bundle::TYPE_CODE) { - $bundleProducts[] = $product; - } - } - - if (empty($bundleProducts)) { - return $resultData; - } - - $optionsMap = $this->getBundleOptionsMap($bundleProducts); - - $optionsMap = $this->hydrateLinks($optionsMap); - - $childrenSkus = []; - $bundleMap = []; - $linkField = $this->getProductLinkField(); - /** @var OptionInterface[] $optionList */ - foreach ($optionsMap as $parentId => $optionList) { - foreach ($resultData as $key => $product) { - if ((int)$product[$linkField] === (int)$parentId) { - $resultData[$key]['bundle_product_options'] = $optionList; - foreach ($optionList as $option) { - if ($option->getSku()) { - $childrenSkus[] = $option->getSku(); - $bundleMap[$product[ProductInterface::SKU]][] = $option->getSku(); - continue; - } - - foreach ($option->getProductLinks() as $link) { - if ($link->getSku()) { - $childrenSkus[] = $link->getSku(); - $bundleMap[$product[ProductInterface::SKU]][] = $link->getSku(); - } - } - } - } - } - } - - if (empty($childrenSkus)) { - return $resultData; - } - - $this->searchCriteriaBuilder->addFilter(ProductInterface::SKU, $childrenSkus, 'in'); - $childProducts = $this->productDataProvider->getList($this->searchCriteriaBuilder->create()); - $resultData = $this->addChildData($childProducts->getItems(), $resultData, $bundleMap); - - return $resultData; - - $bundleMap = []; - foreach ($resultData as $productKey => $product) { - if (isset($product['type_id']) && $product['type_id'] === Bundle::TYPE_CODE) { - if (isset($product['bundle_product_options'])) { - $bundleMap[$product['sku']] = []; - /** @var Option $option */ - foreach ($product['bundle_product_options'] as $optionKey => $option) { - $resultData[$productKey]['items'][$optionKey] - = $option->getData(); - /** @var LinkInterface $link */ - foreach ($option['product_links'] as $link) { - $bundleMap[$product['sku']][] = $link->getSku(); - $childrenSkus[] = $link->getSku(); - $formattedLink = [ - 'product' => new GraphQlNoSuchEntityException( - __('Bundled product not found') - ), - 'price' => $link->getPrice(), - 'position' => $link->getPosition(), - 'id' => $link->getId(), - 'qty' => (int)$link->getQty(), - 'is_default' => (bool)$link->getIsDefault(), - 'price_type' => $this->enumLookup->getEnumValueFromField( - 'PriceTypeEnum', - (string)$link->getPriceType() - ) ?: 'DYNAMIC', - 'can_change_quantity' => $link->getCanChangeQuantity() - ]; - $resultData[$productKey]['items'][$optionKey]['options'][$link['sku']] = $formattedLink; - } - } - } - } - } - } - - /** - * Retrieve bundle option collection with each option list assigned to a parent id key. - * - * Output format: [$parentId => [$option1, $option2...], ...] - * - * @param array $bundleProducts - * @return array - */ - private function getBundleOptionsMap(array $bundleProducts) : array - { - $uniqueKey = $this->getProductLinkField(); - /** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionsCollection */ - $optionsCollection = $this->bundleOption->create()->getResourceCollection(); - // All products in collection will have same store id. - $optionsCollection->joinValues($this->storeManager->getStore()->getId()); - foreach ($bundleProducts as $product) { - $optionsCollection->setProductIdFilter($product[$uniqueKey]); - } - $optionsCollection->setPositionOrder(); - - $this->extensionAttributesJoinProcessor->process($optionsCollection); - if (empty($optionsCollection->getData())) { - return []; - } - - $optionsMap = []; - /** @var \Magento\Bundle\Model\Option $option */ - foreach ($optionsCollection as $option) { - /** @var OptionInterface $optionInterface */ - $optionInterface = $this->optionFactory->create(); - foreach ($bundleProducts as $product) { - if ((int)$product[$uniqueKey] !== (int)$option->getParentId()) { - continue; - } - - $this->dataObjectHelper->populateWithArray( - $optionInterface, - $option->getData(), - \Magento\Bundle\Api\Data\OptionInterface::class - ); - $optionInterface->setOptionId($option->getOptionId()) - ->setTitle($option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle()) - ->setDefaultTitle($option->getDefaultTitle()) - ->setSku($product['sku']); - break; - } - - if ($optionInterface->getOptionId() === null) { - continue; - } - - if (!isset($optionsMap[$option->getParentId()])) { - $optionsMap[(int)$option->getParentId()] = []; - } - - $optionsMap[(int)$option->getParentId()][] = $optionInterface; - } - - return $optionsMap; - } - - /** - * Hydrate links for input options - * - * @param array $optionsMap - * @return array - */ - private function hydrateLinks(array $optionsMap) : array - { - $parentIds = []; - $optionIds = []; - foreach ($optionsMap as $parentId => $optionList) { - $parentIds[] = $parentId; - /** @var OptionInterface $option */ - foreach ($optionList as $option) { - if (in_array($option->getOptionId(), $optionIds)) { - continue; - } - - $optionsIds = []; - } - } - - /** @var Collection $linkCollection */ - $linkCollection = $this->linkCollectionFactory->create(); - $linkCollection->setOptionIdsFilter($optionsIds); - $field = 'parent_product_id'; - foreach ($linkCollection->getSelect()->getPart('from') as $tableAlias => $data) { - if ($data['tableName'] == $linkCollection->getTable('catalog_product_bundle_selection')) { - $field = $tableAlias . '.' . $field; - } - } - - $linkCollection->getSelect() - ->where($field . ' IN (?)', $parentIds); - - $productLinksMap = []; - - /** @var \Magento\Catalog\Model\Product $selection $link */ - foreach ($linkCollection as $link) { - $selectionPriceType = $link->getSelectionPriceType(); - $selectionPrice = $link->getSelectionPriceValue(); - /** @var LinkInterface $productLink */ - $productLink = $this->linkFactory->create(); - $this->dataObjectHelper->populateWithArray( - $productLink, - $link->getData(), - \Magento\Bundle\Api\Data\LinkInterface::class - ); - $productLink->setIsDefault($link->getIsDefault()) - ->setId($link->getSelectionId()) - ->setQty($link->getSelectionQty()) - ->setCanChangeQuantity($link->getSelectionCanChangeQty()) - ->setPrice($selectionPrice) - ->setPriceType($selectionPriceType); - if (!isset($productLinksMap[$productLink->getOptionId()])) { - $productLinksMap[$productLink->getOptionId()] = []; - } - $productLinksMap[$productLink->getOptionId()][] = $productLink; - } - - foreach ($productLinksMap as $optionId => $productLinkList) { - foreach ($optionsMap as $parentId => $optionsList) { - /** @var OptionInterface $option */ - foreach ($optionsList as $optionKey => $option) { - if ((int)$option->getOptionId() === (int)$optionId) { - $optionsMap[$parentId][$optionKey]->setProductLinks($productLinkList); - } - } - } - } - - return $optionsMap; - } - - /** - * Format and add children product data to bundle product response items. - * - * @param \Magento\Catalog\Model\Product[] $childrenProducts - * @param array $resultData - * @param array $bundleMap Map of parent skus and their children they contain [$parentSku => [$child1, $child2...]] - * @return array - */ - private function addChildData(array $childrenProducts, array $resultData, array $bundleMap) : array - { - foreach ($childrenProducts as $childProduct) { - $childData = $this->formatter->format($childProduct); - foreach ($resultData as $productKey => $item) { - if ($item['type_id'] === Bundle::TYPE_CODE - && in_array($childData['sku'], $bundleMap[$item['sku']]) - ) { - $categoryLinks = $this->productResource->getCategoryIds($childProduct); - foreach ($categoryLinks as $position => $categoryLink) { - $childData['category_links'][] = ['position' => $position, 'category_id' => $categoryLink]; - } -// foreach ($item['bundle_product_options'] as $itemKey => $bundleItem) { -// foreach (array_keys($bundleItem['options']) as $optionKey) { -// if ($childData['sku'] === $optionKey) { -// $resultData[$productKey]['items'][$itemKey]['options'][$optionKey]['product'] -// = $childData; -// $resultData[$productKey]['items'][$itemKey]['options'][$optionKey]['label'] -// = $childData['name']; -// } -// } -// } - } - } - } - - return $resultData; - } - - /** - * Get link field name for unique product identifier. - * - * @return string - */ - private function getProductLinkField() : string - { - if (empty($this->productLinkField)) { - $this->productLinkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); - } - - return $this->productLinkField; - } -} From 3074f6ea2dcfab62c0812110282d44e4f2ed7f44 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Thu, 15 Mar 2018 14:55:10 -0500 Subject: [PATCH 090/668] MAGETWO-88934: Add return type to private method. --- .../Magento/BundleGraphQl/Model/Resolver/Links/Collection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php index 5acc8582de8b1..0003ddedc5605 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php @@ -91,7 +91,7 @@ public function getLinksForOptionId(int $optionId) : ?array * * @return array */ - private function fetch() + private function fetch() : array { if (empty($this->optionIds) || empty($this->parentIds) || !empty($this->links)) { return $this->links; From 915e11a2ce355d4062e511536ab523ab83373453 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Thu, 15 Mar 2018 15:24:56 -0500 Subject: [PATCH 091/668] MAGETWO-88934: Finish bundle resolver refactoring --- .../Resolver/Product/Fields/DynamicPrice.php | 57 ++++++++++++++ .../Resolver/Product/Fields/DynamicSku.php | 57 ++++++++++++++ .../Resolver/Product/Fields/DynamicWeight.php | 57 ++++++++++++++ .../Resolver/Product/Fields/PriceView.php | 66 ++++++++++++++++ .../Product/Fields/ShipBundleItems.php | 66 ++++++++++++++++ .../Product/Formatter/BundleOptions.php | 77 ------------------- .../Magento/BundleGraphQl/etc/graphql.xml | 10 +-- .../Magento/BundleGraphQl/etc/graphql/di.xml | 7 -- 8 files changed, 308 insertions(+), 89 deletions(-) create mode 100644 app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/DynamicPrice.php create mode 100644 app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/DynamicSku.php create mode 100644 app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/DynamicWeight.php create mode 100644 app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/PriceView.php create mode 100644 app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/ShipBundleItems.php delete mode 100644 app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BundleOptions.php diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/DynamicPrice.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/DynamicPrice.php new file mode 100644 index 0000000000000..c357d39e678fc --- /dev/null +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/DynamicPrice.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + + +namespace Magento\BundleGraphQl\Model\Resolver\Product\Fields; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Bundle\Model\Product\Type as Bundle; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; + +/** + * {@inheritdoc} + */ +class DynamicPrice implements ResolverInterface +{ + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param ValueFactory $valueFactory + */ + public function __construct(ValueFactory $valueFactory) + { + $this->valueFactory = $valueFactory; + } + + /** + * {@inheritdoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + $result = null; + if ($value['type_id'] === Bundle::TYPE_CODE) { + $result = isset($value['price_type']) ? $value['price_type'] : null; + } + + return $this->valueFactory->create( + function () use ($result) { + return $result; + } + ); + } +} diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/DynamicSku.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/DynamicSku.php new file mode 100644 index 0000000000000..2d54eebda8eb9 --- /dev/null +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/DynamicSku.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + + +namespace Magento\BundleGraphQl\Model\Resolver\Product\Fields; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Bundle\Model\Product\Type as Bundle; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; + +/** + * {@inheritdoc} + */ +class DynamicSku implements ResolverInterface +{ + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param ValueFactory $valueFactory + */ + public function __construct(ValueFactory $valueFactory) + { + $this->valueFactory = $valueFactory; + } + + /** + * {@inheritdoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + $result = null; + if ($value['type_id'] === Bundle::TYPE_CODE) { + $result = isset($value['sku_type']) ? $value['sku_type'] : null; + } + + return $this->valueFactory->create( + function () use ($result) { + return $result; + } + ); + } +} diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/DynamicWeight.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/DynamicWeight.php new file mode 100644 index 0000000000000..53987038ca1c1 --- /dev/null +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/DynamicWeight.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + + +namespace Magento\BundleGraphQl\Model\Resolver\Product\Fields; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Bundle\Model\Product\Type as Bundle; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; + +/** + * {@inheritdoc} + */ +class DynamicWeight implements ResolverInterface +{ + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param ValueFactory $valueFactory + */ + public function __construct(ValueFactory $valueFactory) + { + $this->valueFactory = $valueFactory; + } + + /** + * {@inheritdoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + $result = null; + if ($value['type_id'] === Bundle::TYPE_CODE) { + $result = isset($value['weight_type']) ? $value['weight_type'] : null; + } + + return $this->valueFactory->create( + function () use ($result) { + return $result; + } + ); + } +} diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/PriceView.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/PriceView.php new file mode 100644 index 0000000000000..3dfb2d4aef85e --- /dev/null +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/PriceView.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + + +namespace Magento\BundleGraphQl\Model\Resolver\Product\Fields; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Query\EnumLookup; +use Magento\Bundle\Model\Product\Type as Bundle; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; + +/** + * {@inheritdoc} + */ +class PriceView implements ResolverInterface +{ + /** + * @var EnumLookup + */ + private $enumLookup; + + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param EnumLookup $enumLookup + * @param ValueFactory $valueFactory + */ + public function __construct(EnumLookup $enumLookup, ValueFactory $valueFactory) + { + $this->enumLookup = $enumLookup; + $this->valueFactory = $valueFactory; + } + + /** + * {@inheritdoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + if ($value['type_id'] === Bundle::TYPE_CODE) { + $result = isset($value['price_view']) + ? $this->enumLookup->getEnumValueFromField('PriceViewEnum', $value['price_view']) : null; + return $this->valueFactory->create( + function () use ($result) { + return $result; + } + ); + } + + return null; + } +} diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/ShipBundleItems.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/ShipBundleItems.php new file mode 100644 index 0000000000000..15e34413d467c --- /dev/null +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Fields/ShipBundleItems.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + + +namespace Magento\BundleGraphQl\Model\Resolver\Product\Fields; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Query\EnumLookup; +use Magento\Bundle\Model\Product\Type as Bundle; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; + +/** + * {@inheritdoc} + */ +class ShipBundleItems implements ResolverInterface +{ + /** + * @var EnumLookup + */ + private $enumLookup; + + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param EnumLookup $enumLookup + * @param ValueFactory $valueFactory + */ + public function __construct(EnumLookup $enumLookup, ValueFactory $valueFactory) + { + $this->enumLookup = $enumLookup; + $this->valueFactory = $valueFactory; + } + + /** + * {@inheritdoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + if ($value['type_id'] === Bundle::TYPE_CODE) { + $result = isset($value['price_view']) + ? $this->enumLookup->getEnumValueFromField('ShipBundleItemsEnum', $value['shipment_type']) : null; + return $this->valueFactory->create( + function () use ($result) { + return $result; + } + ); + } + + return null; + } +} diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BundleOptions.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BundleOptions.php deleted file mode 100644 index 9bf4952921561..0000000000000 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BundleOptions.php +++ /dev/null @@ -1,77 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\BundleGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; - -use Magento\Catalog\Model\Product; -use Magento\Bundle\Model\Product\Type as Bundle; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; -use Magento\Framework\Exception\RuntimeException; -use Magento\Framework\GraphQl\Query\EnumLookup; - -/** - * Post formatting data to set main fields and options for bundle product - */ -class BundleOptions implements FormatterInterface -{ - /** - * @var EnumLookup - */ - private $enumLookup; - - /** - * BundleOptions constructor. - * @param EnumLookup $enumLookup - */ - public function __construct(EnumLookup $enumLookup) - { - $this->enumLookup = $enumLookup; - } - - /** - * Add bundle options and options to configurable types - * - * {@inheritdoc} - */ - public function format(Product $product, array $productData = []) : array - { - if ($product->getTypeId() === Bundle::TYPE_CODE) { - $productData = $this->formatBundleAttributes($productData); - } - - return $productData; - } - - /** - * Format bundle specific top level attributes from product - * - * @param array $product - * @return array - * @throws RuntimeException - */ - private function formatBundleAttributes(array $product) : array - { - if (isset($product['price_view'])) { - $product['price_view'] - = $this->enumLookup->getEnumValueFromField('PriceViewEnum', $product['price_view']); - } - if (isset($product['shipment_type'])) { - $product['ship_bundle_items'] - = $this->enumLookup->getEnumValueFromField('ShipBundleItemsEnum', $product['shipment_type']); - } - if (isset($product['price_type'])) { - $product['dynamic_price'] = !(bool)$product['price_type']; - } - if (isset($product['sku_type'])) { - $product['dynamic_sku'] = !(bool)$product['sku_type']; - } - if (isset($product['weight_type'])) { - $product['dynamic_weight'] = !(bool)$product['weight_type']; - } - return $product; - } -} diff --git a/app/code/Magento/BundleGraphQl/etc/graphql.xml b/app/code/Magento/BundleGraphQl/etc/graphql.xml index 3cd2dfd722bc8..e464c338ae3eb 100644 --- a/app/code/Magento/BundleGraphQl/etc/graphql.xml +++ b/app/code/Magento/BundleGraphQl/etc/graphql.xml @@ -8,11 +8,11 @@ <implements interface="ProductInterface" copyFields="true"/> <implements interface="PhysicalProductInterface" copyFields="true"/> <implements interface="CustomizableProductInterface" copyFields="true"/> - <field xsi:type="ObjectOutputField" name="price_view" type="PriceViewEnum" description="One of PRICE_RANGE or AS_LOW_AS"/> - <field xsi:type="ScalarOutputField" name="dynamic_price" type="Boolean" description="Indicates whether the bundle product has a dynamic price."/> - <field xsi:type="ScalarOutputField" name="dynamic_sku" type="Boolean" description="Indicates whether the bundle product has a dynamic SKU."/> - <field xsi:type="ObjectOutputField" name="ship_bundle_items" type="ShipBundleItemsEnum" description="Indicates whether to ship bundle items together or individually."/> - <field xsi:type="ScalarOutputField" name="dynamic_weight" type="Boolean" description="Indicates whether the bundle product has a dynamically calculated weight."/> + <field xsi:type="ObjectOutputField" name="price_view" type="PriceViewEnum" resolver="Magento\BundleGraphQl\Model\Resolver\Product\Fields\PriceView" description="One of PRICE_RANGE or AS_LOW_AS"/> + <field xsi:type="ScalarOutputField" name="dynamic_price" type="Boolean" resolver="Magento\BundleGraphQl\Model\Resolver\Product\Fields\DynamicPrice" description="Indicates whether the bundle product has a dynamic price."/> + <field xsi:type="ScalarOutputField" name="dynamic_sku" type="Boolean" resolver="Magento\BundleGraphQl\Model\Resolver\Product\Fields\DynamicSku" description="Indicates whether the bundle product has a dynamic SKU."/> + <field xsi:type="ObjectOutputField" name="ship_bundle_items" type="ShipBundleItemsEnum" resolver="Magento\BundleGraphQl\Model\Resolver\Product\Fields\ShipBundleItems" description="Indicates whether to ship bundle items together or individually."/> + <field xsi:type="ScalarOutputField" name="dynamic_weight" type="Boolean" resolver="Magento\BundleGraphQl\Model\Resolver\Product\Fields\DynamicWeight" description="Indicates whether the bundle product has a dynamically calculated weight."/> <field xsi:type="ObjectArrayOutputField" name="items" itemType="BundleItem" resolver="Magento\BundleGraphQl\Model\Resolver\BundleItems" description="An array containing information about individual bundle items."/> </type> <type xsi:type="OutputType" name="BundleItem"> diff --git a/app/code/Magento/BundleGraphQl/etc/graphql/di.xml b/app/code/Magento/BundleGraphQl/etc/graphql/di.xml index 78c0e505bfcf7..b57db1f80fdeb 100644 --- a/app/code/Magento/BundleGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/BundleGraphQl/etc/graphql/di.xml @@ -6,13 +6,6 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterComposite"> - <arguments> - <argument name="formatterInstances" xsi:type="array"> - <item name="add_bundle_data" xsi:type="object">Magento\BundleGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter\BundleOptions</item> - </argument> - </arguments> - </type> <type name="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> <arguments> <argument name="productTypeNameResolvers" xsi:type="array"> From bbe91fba791ad8733e1ca488148d5488d778b6d5 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Thu, 15 Mar 2018 16:46:29 -0500 Subject: [PATCH 092/668] MAGETWO-89292: Implement SDL from prototype - add prototype and modifying it to support itemType --- .../Framework/GraphQl/Config/Data/Argument.php | 4 +++- .../Framework/GraphQl/Config/Data/DataFactory.php | 14 ++++++++------ .../Framework/GraphQl/Config/Data/Field.php | 8 +++++--- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php index 8429c1ed068a5..5a61787414695 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php @@ -61,6 +61,7 @@ class Argument implements FieldInterface * @param string $description * @param bool $required * @param bool $isList + * @param $itemType $itemType * @param bool $itemsRequired * @param string $default */ @@ -71,11 +72,12 @@ public function __construct( string $description, bool $required, bool $isList, + string $itemType = '', bool $itemsRequired = false, string $default = null ) { $this->name = $name; - $this->type = $type; + $this->type = $isList ? $itemType : $type; $this->baseType = $baseType; $this->description = $description; $this->required = $required; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php index b7ffd5f836b8e..45e722f66c8dc 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php @@ -50,8 +50,9 @@ public function createField( 'type' => $fieldData['type'], 'required' => isset($fieldData['required']) ? $fieldData['required'] : false, 'isList' => isset($fieldData['itemType']), - 'resolver' => isset($fieldData['resolver']) ? $fieldData['resolver'] : "", - 'description' => isset($fieldData['description']) ? $fieldData['description'] : "", + 'itemType' => isset($fieldData['itemType']) ? $fieldData['itemType'] : '', + 'resolver' => isset($fieldData['resolver']) ? $fieldData['resolver'] : '', + 'description' => isset($fieldData['description']) ? $fieldData['description'] : '', 'arguments' => $arguments ] ); @@ -74,10 +75,11 @@ public function createArgument( [ 'name' => $argumentData['name'], 'type' => isset($argumentData['itemType']) ? $argumentData['itemType'] : $argumentData['type'], - 'baseType' => isset($argumentData['baseType']) ? $argumentData['baseType'] : "", - 'description' => isset($argumentData['description']) ? $argumentData['description'] : "", + 'baseType' => isset($argumentData['baseType']) ? $argumentData['baseType'] : '', + 'description' => isset($argumentData['description']) ? $argumentData['description'] : '', 'required' => isset($argumentData['required']) ? $argumentData['required'] : false, 'isList' => isset($argumentData['itemType']), + 'itemType' => isset($argumentData['itemType']) ? $argumentData['itemType'] : '', 'itemsRequired' => isset($argumentData['itemsRequired']) ? $argumentData['itemsRequired'] : false, 'default' => isset($argumentData['default']) ? $argumentData['default'] : null ] @@ -104,7 +106,7 @@ public function createType( 'name' => $typeData['name'], 'fields' => $fields, 'interfaces' => isset($typeData['implements']) ? $typeData['implements'] : [], - 'description' => isset($typeData['description']) ? $typeData['description'] : "" + 'description' => isset($typeData['description']) ? $typeData['description'] : '' ] ); } @@ -130,7 +132,7 @@ public function createInterface( 'name' => $interfaceData['name'], 'typeResolver' => $interfaceData['typeResolver'], 'fields' => $fields, - 'description' => isset($interfaceData['description']) ? $interfaceData['description'] : "" + 'description' => isset($interfaceData['description']) ? $interfaceData['description'] : '' ] ); } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php index 26888a73a3bb7..177f554de2fba 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php @@ -51,6 +51,7 @@ class Field implements OutputFieldInterface * @param string $type * @param bool $required * @param bool $isList + * @param $itemType $itemType * @param string $resolver * @param string $description * @param array $arguments @@ -60,12 +61,13 @@ public function __construct( string $type, bool $required, bool $isList, - string $resolver = "", - string $description = "", + string $itemType = '', + string $resolver = '', + string $description = '', array $arguments = [] ) { $this->name = $name; - $this->type = $type; + $this->type = $isList ? $itemType : $type; $this->required = $required; $this->isList = $isList; $this->resolver = $resolver; From 12737ec32509fbbbf36ff74a551c82a09f4924d9 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Thu, 15 Mar 2018 16:59:14 -0500 Subject: [PATCH 093/668] MAGETWO-89292: Implement SDL from prototype - add strict type to graphql Reader --- .../GraphQl/Config/GraphQlReader.php | 58 ++++++++++++++----- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php index cff510244ab65..3b4c100f584ae 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\Framework\GraphQl\Config; @@ -35,7 +36,7 @@ public function __construct( $this->fileName = $fileName; } - public function read($scope = null) + public function read($scope = null) : array { $result = []; $scope = $scope ?: $this->defaultScope; @@ -96,7 +97,11 @@ public function read($scope = null) } - private function readEnumTypeMeta(\GraphQL\Type\Definition\EnumType $typeMeta) + /** + * @param \GraphQL\Type\Definition\EnumType $typeMeta + * @return array + */ + private function readEnumTypeMeta(\GraphQL\Type\Definition\EnumType $typeMeta) : array { $result = [ 'name' => $typeMeta->name, @@ -114,12 +119,20 @@ private function readEnumTypeMeta(\GraphQL\Type\Definition\EnumType $typeMeta) return $result; } - private function isScalarType($type) + /** + * @param string $type + * @return bool + */ + private function isScalarType(string $type) : bool { return in_array($type, ['String', 'Int', 'Float', 'Boolean', 'ID']); } - private function readObjectTypeMeta(\GraphQL\Type\Definition\ObjectType $typeMeta) + /** + * @param \GraphQL\Type\Definition\ObjectType $typeMeta + * @return array + */ + private function readObjectTypeMeta(\GraphQL\Type\Definition\ObjectType $typeMeta) : array { $typeName = $typeMeta->name; $result = [ @@ -146,7 +159,11 @@ private function readObjectTypeMeta(\GraphQL\Type\Definition\ObjectType $typeMet return $result; } - private function readInputObjectTypeMeta(\GraphQL\Type\Definition\InputObjectType $typeMeta) + /** + * @param \GraphQL\Type\Definition\InputObjectType $typeMeta + * @return array + */ + private function readInputObjectTypeMeta(\GraphQL\Type\Definition\InputObjectType $typeMeta) : array { $typeName = $typeMeta->name; $result = [ @@ -161,7 +178,11 @@ private function readInputObjectTypeMeta(\GraphQL\Type\Definition\InputObjectTyp return $result; } - private function readInterfaceTypeMeta(\GraphQL\Type\Definition\InterfaceType $typeMeta) + /** + * @param \GraphQL\Type\Definition\InterfaceType $typeMeta + * @return array + */ + private function readInterfaceTypeMeta(\GraphQL\Type\Definition\InterfaceType $typeMeta) : array { $typeName = $typeMeta->name; $result = [ @@ -182,7 +203,11 @@ private function readInterfaceTypeMeta(\GraphQL\Type\Definition\InterfaceType $t return $result; } - private function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) + /** + * @param \GraphQL\Type\Definition\FieldDefinition $fieldMeta + * @return array + */ + private function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) : array { $fieldName = $fieldMeta->name; $fieldTypeMeta = $fieldMeta->getType(); @@ -216,7 +241,11 @@ private function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMe return $result; } - private function readInputObjectFieldMeta(\GraphQL\Type\Definition\InputObjectField $fieldMeta) + /** + * @param \GraphQL\Type\Definition\InputObjectField $fieldMeta + * @return array + */ + private function readInputObjectFieldMeta(\GraphQL\Type\Definition\InputObjectField $fieldMeta) : array { $fieldName = $fieldMeta->name; $typeMeta = $fieldMeta->getType(); @@ -234,10 +263,11 @@ private function readInputObjectFieldMeta(\GraphQL\Type\Definition\InputObjectFi /** * @param $meta * @param string $parameterType Argument|OutputField|InputField - * @return mixed + * @return array */ - private function readTypeMeta($meta, $parameterType = 'Argument') + private function readTypeMeta($meta, $parameterType = 'Argument') : array { + $result = []; if ($meta instanceof \GraphQL\Type\Definition\NonNull) { $result['required'] = true; $meta = $meta->getWrappedType(); @@ -255,7 +285,7 @@ private function readTypeMeta($meta, $parameterType = 'Argument') $result['description'] = $itemTypeMeta->description; $itemTypeName = $itemTypeMeta->name; $result['itemType'] = $itemTypeName; - if ($this->isScalarType($itemTypeMeta)) { + if ($this->isScalarType((string)$itemTypeMeta)) { $result['type'] = 'ScalarArray' . $parameterType; } else { $result['type'] = 'ObjectArray' . $parameterType; @@ -271,7 +301,7 @@ private function readTypeMeta($meta, $parameterType = 'Argument') * @param \GraphQL\Type\Definition\FieldDefinition $fieldMeta * @return string|null */ - private function readFieldResolver(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) + private function readFieldResolver(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) : ?string { /** @var \GraphQL\Language\AST\NodeList $directives */ $directives = $fieldMeta->astNode->directives; @@ -291,7 +321,7 @@ private function readFieldResolver(\GraphQL\Type\Definition\FieldDefinition $fie * @param \GraphQL\Type\Definition\InterfaceType $interfaceTypeMeta * @return string|null */ - private function readInterfaceTypeResolver(\GraphQL\Type\Definition\InterfaceType $interfaceTypeMeta) + private function readInterfaceTypeResolver(\GraphQL\Type\Definition\InterfaceType $interfaceTypeMeta) : ?string { /** @var \GraphQL\Language\AST\NodeList $directives */ $directives = $interfaceTypeMeta->astNode->directives; @@ -311,7 +341,7 @@ private function readInterfaceTypeResolver(\GraphQL\Type\Definition\InterfaceTyp * @param string $graphQlSchemaContent * @return array [$typeName => $typeDeclaration, ...] */ - private function parseTypes($graphQlSchemaContent) + private function parseTypes($graphQlSchemaContent) : array { $typeKindsPattern = '(type|interface|union|enum|input)'; $typeNamePattern = '[_A-Za-z][_0-9A-Za-z]*'; From 12da624aca316f2b8a7f71c14c048c91b9eec28e Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@magento.com> Date: Fri, 16 Mar 2018 12:17:03 -0500 Subject: [PATCH 094/668] MAGETWO-89178: Modify all code and run integration and functional tests - Introspection query test --- .../GraphQl/IntrospectionQueryTest.php | 66 ++++++++++++++++ .../GraphQl/_files/query_introspection.php | 75 +++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/IntrospectionQueryTest.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/_files/query_introspection.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/IntrospectionQueryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/IntrospectionQueryTest.php new file mode 100644 index 0000000000000..b2facbfc8712d --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/IntrospectionQueryTest.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\GraphQl; + + +use Magento\TestFramework\TestCase\GraphQlAbstract; + +class IntrospectionQueryTest extends GraphQlAbstract +{ + /** + * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testIntrospectionQueryWithFieldArgs() + { + $query + = <<<QUERY +query IntrospectionQuery { + __schema { + queryType { name } + types{ + ...FullType + } + } + } +fragment FullType on __Type{ + name + kind + fields(includeDeprecated:true){ + name + args{ + ...InputValue + } + } + } + +fragment TypeRef on __Type { + kind + name + ofType{ + kind + name + } +} +fragment InputValue on __InputValue { + name + description + type { ...TypeRef } + defaultValue +} +QUERY; + + $response = $this->graphQlQuery($query); + $schemaResponseFields = $response['__schema']['types'][0]['fields']; + $expectedOutputArray = require __DIR__ . '/_files/query_introspection.php'; + foreach($expectedOutputArray as $searchTerm){ + $this->assertTrue((in_array($searchTerm, $schemaResponseFields)), 'Missing field array in the schema response'); + } + } +} + + diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/_files/query_introspection.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/_files/query_introspection.php new file mode 100644 index 0000000000000..f54c8bfae10a1 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/_files/query_introspection.php @@ -0,0 +1,75 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +return [ + + [ + 'name' => 'customAttributeMetadata', + 'args' => + [ + [ + 'name' => 'attributes', + 'description' => '', + 'type' => + [ + 'kind' => 'NON_NULL', + 'name' => null, + 'ofType' => + [ + 'kind' => 'LIST', + 'name' => null, + ] + ], + 'defaultValue' => null, + ] + ] + ], + [ + 'name' => 'testItem', + 'args' => + [ + [ + 'name' => 'id', + 'description' => '', + 'type' => + [ + 'kind' => 'NON_NULL', + 'name' => null, + 'ofType' => + [ + 'kind' => 'SCALAR', + 'name' => 'Int', + ] + + ], + 'defaultValue' => null, + + ] + ] + + ], + [ + 'name' => 'urlResolver', + 'args' => + [ + [ + 'name' => 'url', + 'description' => '', + 'type' => + [ + 'kind' => 'NON_NULL', + 'name' => null, + 'ofType' => + [ + 'kind' => 'SCALAR', + 'name' => 'String', + ] + ], + 'defaultValue' => null, + ] + ] + + ] +]; From d262026f88d00a29f07a1d7791b2ec8174230cd4 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Fri, 16 Mar 2018 12:30:36 -0500 Subject: [PATCH 095/668] MAGETWO-89321: Misconfigured composer.json and composer.lock --- app/code/Magento/Signifyd/composer.json | 2 +- composer.lock | 1030 ++++++++++++----------- 2 files changed, 540 insertions(+), 492 deletions(-) diff --git a/app/code/Magento/Signifyd/composer.json b/app/code/Magento/Signifyd/composer.json index df0817be2ba6d..ed8277508736a 100644 --- a/app/code/Magento/Signifyd/composer.json +++ b/app/code/Magento/Signifyd/composer.json @@ -14,7 +14,7 @@ "magento/module-payment": "100.3.*", "magento/module-sales": "100.3.*", "magento/module-store": "100.3.*", - "php": "~7.1.3||~7.2.0", + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/module-config": "100.3.*" diff --git a/composer.lock b/composer.lock index 8509554e81739..69c255a51589e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "03ece269ddc8227e813e176dad41a986", + "hash": "0b4905ef278c7a520397bdfb3b62b288", + "content-hash": "e45676f85a1d6027c7cc7d91ff5583de", "packages": [ { "name": "braintree/braintree_php", @@ -51,25 +52,22 @@ } ], "description": "Braintree PHP Client Library", - "time": "2017-02-16T19:59:04+00:00" + "time": "2017-02-16 19:59:04" }, { "name": "colinmollenhour/cache-backend-file", - "version": "1.4", + "version": "v1.4.1", "source": { "type": "git", "url": "https://github.com/colinmollenhour/Cm_Cache_Backend_File.git", - "reference": "51251b80a817790eb624fbe2afc882c14f3c4fb0" + "reference": "3146110d4d0f79e016a4f99c36794d5ed50c4652" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_File/zipball/51251b80a817790eb624fbe2afc882c14f3c4fb0", - "reference": "51251b80a817790eb624fbe2afc882c14f3c4fb0", + "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_File/zipball/3146110d4d0f79e016a4f99c36794d5ed50c4652", + "reference": "3146110d4d0f79e016a4f99c36794d5ed50c4652", "shasum": "" }, - "require": { - "magento-hackathon/magento-composer-installer": "*" - }, "type": "magento-module", "autoload": { "classmap": [ @@ -87,7 +85,7 @@ ], "description": "The stock Zend_Cache_Backend_File backend has extremely poor performance for cleaning by tags making it become unusable as the number of cached items increases. This backend makes many changes resulting in a huge performance boost, especially for tag cleaning.", "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_File", - "time": "2016-05-02T16:24:47+00:00" + "time": "2018-03-02 17:44:39" }, { "name": "colinmollenhour/cache-backend-redis", @@ -123,7 +121,7 @@ ], "description": "Zend_Cache backend using Redis with full support for tags.", "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis", - "time": "2017-03-25T04:54:24+00:00" + "time": "2017-03-25 04:54:24" }, { "name": "colinmollenhour/credis", @@ -162,7 +160,7 @@ ], "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", "homepage": "https://github.com/colinmollenhour/credis", - "time": "2015-11-28T01:20:04+00:00" + "time": "2015-11-28 01:20:04" }, { "name": "colinmollenhour/php-redis-session-abstract", @@ -199,7 +197,7 @@ ], "description": "A Redis-based session handler with optimistic locking", "homepage": "https://github.com/colinmollenhour/php-redis-session-abstract", - "time": "2018-01-08T14:53:13+00:00" + "time": "2018-01-08 14:53:13" }, { "name": "composer/ca-bundle", @@ -255,39 +253,39 @@ "ssl", "tls" ], - "time": "2017-11-29T09:37:33+00:00" + "time": "2017-11-29 09:37:33" }, { "name": "composer/composer", - "version": "1.4.1", + "version": "1.6.3", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "7ee2a5e1cf32e9c8439445fe8dce2c046c2abebd" + "reference": "88a69fda0f2187ad8714cedffd7a8872dceaa4c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/7ee2a5e1cf32e9c8439445fe8dce2c046c2abebd", - "reference": "7ee2a5e1cf32e9c8439445fe8dce2c046c2abebd", + "url": "https://api.github.com/repos/composer/composer/zipball/88a69fda0f2187ad8714cedffd7a8872dceaa4c2", + "reference": "88a69fda0f2187ad8714cedffd7a8872dceaa4c2", "shasum": "" }, "require": { "composer/ca-bundle": "^1.0", "composer/semver": "^1.0", - "composer/spdx-licenses": "^1.0", + "composer/spdx-licenses": "^1.2", "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", "php": "^5.3.2 || ^7.0", "psr/log": "^1.0", "seld/cli-prompt": "^1.0", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.0", - "symfony/console": "^2.7 || ^3.0", - "symfony/filesystem": "^2.7 || ^3.0", - "symfony/finder": "^2.7 || ^3.0", - "symfony/process": "^2.7 || ^3.0" + "symfony/console": "^2.7 || ^3.0 || ^4.0", + "symfony/filesystem": "^2.7 || ^3.0 || ^4.0", + "symfony/finder": "^2.7 || ^3.0 || ^4.0", + "symfony/process": "^2.7 || ^3.0 || ^4.0" }, "require-dev": { - "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit": "^4.8.35 || ^5.7", "phpunit/phpunit-mock-objects": "^2.3 || ^3.0" }, "suggest": { @@ -301,7 +299,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.6-dev" } }, "autoload": { @@ -332,7 +330,7 @@ "dependency", "package" ], - "time": "2017-03-10T08:29:45+00:00" + "time": "2018-01-31 15:28:18" }, { "name": "composer/semver", @@ -394,7 +392,7 @@ "validation", "versioning" ], - "time": "2016-08-30T16:08:34+00:00" + "time": "2016-08-30 16:08:34" }, { "name": "composer/spdx-licenses", @@ -455,7 +453,7 @@ "spdx", "validator" ], - "time": "2018-01-31T13:17:27+00:00" + "time": "2018-01-31 13:17:27" }, { "name": "container-interop/container-interop", @@ -486,20 +484,20 @@ ], "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", "homepage": "https://github.com/container-interop/container-interop", - "time": "2017-02-14T19:40:03+00:00" + "time": "2017-02-14 19:40:03" }, { "name": "justinrainbow/json-schema", - "version": "5.2.6", + "version": "5.2.7", "source": { "type": "git", "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "d283e11b6e14c6f4664cf080415c4341293e5bbd" + "reference": "8560d4314577199ba51bf2032f02cd1315587c23" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/d283e11b6e14c6f4664cf080415c4341293e5bbd", - "reference": "d283e11b6e14c6f4664cf080415c4341293e5bbd", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/8560d4314577199ba51bf2032f02cd1315587c23", + "reference": "8560d4314577199ba51bf2032f02cd1315587c23", "shasum": "" }, "require": { @@ -508,7 +506,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "^2.1", "json-schema/json-schema-test-suite": "1.2.0", - "phpunit/phpunit": "^4.8.22" + "phpunit/phpunit": "^4.8.35" }, "bin": [ "bin/validate-json" @@ -552,29 +550,29 @@ "json", "schema" ], - "time": "2017-10-21T13:15:38+00:00" + "time": "2018-02-14 22:26:30" }, { "name": "magento/composer", - "version": "1.2.0", + "version": "1.3.0.x-dev", "source": { "type": "git", "url": "https://github.com/magento/composer.git", - "reference": "130753af2b755f1967e253deb661225942bb302c" + "reference": "21e4019f051513be041f5611fab717af63b5451e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/composer/zipball/130753af2b755f1967e253deb661225942bb302c", - "reference": "130753af2b755f1967e253deb661225942bb302c", + "url": "https://api.github.com/repos/magento/composer/zipball/21e4019f051513be041f5611fab717af63b5451e", + "reference": "21e4019f051513be041f5611fab717af63b5451e", "shasum": "" }, "require": { - "composer/composer": "1.4.1", - "php": "~5.5.0|~5.6.0|~7.0.0|~7.1.0", - "symfony/console": "~2.3, !=2.7.0" + "composer/composer": "~1.6.0", + "php": "~7.1.3|~7.2.0", + "symfony/console": "~4.0.0" }, "require-dev": { - "phpunit/phpunit": "4.1.0" + "phpunit/phpunit": "~7.0.0" }, "type": "library", "autoload": { @@ -588,7 +586,7 @@ "AFL-3.0" ], "description": "Magento composer library helps to instantiate Composer application and run composer commands.", - "time": "2017-04-24T09:57:02+00:00" + "time": "2018-02-23 15:57:04" }, { "name": "magento/magento-composer-installer", @@ -667,22 +665,29 @@ "composer-installer", "magento" ], - "time": "2017-12-29T16:45:24+00:00" + "time": "2017-12-29 16:45:24" }, { "name": "magento/zendframework1", - "version": "1.13.1", + "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/magento/zf1.git", - "reference": "e2693f047bb7ccb8affa8f72ea40269f4c9f4fbf" + "url": "https://github.com/magento-engcom/zf1-php-7.2-support.git", + "reference": "df32cb041603119a448d4634f7d545ab85a8f68a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/zf1/zipball/e2693f047bb7ccb8affa8f72ea40269f4c9f4fbf", - "reference": "e2693f047bb7ccb8affa8f72ea40269f4c9f4fbf", + "url": "https://api.github.com/repos/magento-engcom/zf1-php-7.2-support/zipball/df32cb041603119a448d4634f7d545ab85a8f68a", + "reference": "df32cb041603119a448d4634f7d545ab85a8f68a", "shasum": "" }, + "archive": { + "exclude": [ + "/demos", + "/documentation", + "/tests" + ] + }, "require": { "php": ">=5.2.11" }, @@ -701,7 +706,6 @@ "Zend_": "library/" } }, - "notification-url": "https://packagist.org/downloads/", "include-path": [ "library/" ], @@ -711,10 +715,14 @@ "description": "Magento Zend Framework 1", "homepage": "http://framework.zend.com/", "keywords": [ - "ZF1", - "framework" + "framework", + "zf1" ], - "time": "2017-06-21T14:56:23+00:00" + "support": { + "source": "https://github.com/magento-engcom/zf1-php-7.2-support/tree/master", + "issues": "https://github.com/magento-engcom/zf1-php-7.2-support/issues" + }, + "time": "2018-03-14 21:49:31" }, { "name": "monolog/monolog", @@ -792,7 +800,7 @@ "logging", "psr-3" ], - "time": "2017-06-19T01:22:40+00:00" + "time": "2017-06-19 01:22:40" }, { "name": "oyejorge/less.php", @@ -854,7 +862,7 @@ "php", "stylesheet" ], - "time": "2017-03-28T22:19:25+00:00" + "time": "2017-03-28 22:19:25" }, { "name": "paragonie/random_compat", @@ -902,7 +910,7 @@ "pseudorandom", "random" ], - "time": "2017-09-27T21:40:39+00:00" + "time": "2017-09-27 21:40:39" }, { "name": "pelago/emogrifier", @@ -971,7 +979,7 @@ "email", "pre-processing" ], - "time": "2018-01-05T23:30:21+00:00" + "time": "2018-01-05 23:30:21" }, { "name": "php-amqplib/php-amqplib", @@ -1025,20 +1033,69 @@ "queue", "rabbitmq" ], - "time": "2015-08-11T12:30:09+00:00" + "time": "2015-08-11 12:30:09" + }, + { + "name": "phpseclib/mcrypt_compat", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/mcrypt_compat.git", + "reference": "034ee0e920c70b589196d0bb0a7e8babae5fce08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/mcrypt_compat/zipball/034ee0e920c70b589196d0bb0a7e8babae5fce08", + "reference": "034ee0e920c70b589196d0bb0a7e8babae5fce08", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpseclib/phpseclib": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35|^5.7|^6.0" + }, + "suggest": { + "ext-openssl": "Will enable faster cryptographic operations" + }, + "type": "library", + "autoload": { + "files": [ + "lib/mcrypt.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "homepage": "http://phpseclib.sourceforge.net" + } + ], + "description": "PHP 7.1 polyfill for the mcrypt extension from PHP <= 7.0", + "keywords": [ + "cryptograpy", + "encryption", + "mcrypt" + ], + "time": "2018-01-13 23:07:52" }, { "name": "phpseclib/phpseclib", - "version": "2.0.9", + "version": "2.0.10", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "c9a3fe35e20eb6eeaca716d6a23cde03f52d1558" + "reference": "d305b780829ea4252ed9400b3f5937c2c99b51d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/c9a3fe35e20eb6eeaca716d6a23cde03f52d1558", - "reference": "c9a3fe35e20eb6eeaca716d6a23cde03f52d1558", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/d305b780829ea4252ed9400b3f5937c2c99b51d4", + "reference": "d305b780829ea4252ed9400b3f5937c2c99b51d4", "shasum": "" }, "require": { @@ -1046,7 +1103,7 @@ }, "require-dev": { "phing/phing": "~2.7", - "phpunit/phpunit": "~4.0", + "phpunit/phpunit": "^4.8.35|^5.7|^6.0", "sami/sami": "~2.0", "squizlabs/php_codesniffer": "~2.0" }, @@ -1117,7 +1174,7 @@ "x.509", "x509" ], - "time": "2017-11-29T06:38:08+00:00" + "time": "2018-02-19 04:29:13" }, { "name": "psr/container", @@ -1166,7 +1223,7 @@ "container-interop", "psr" ], - "time": "2017-02-14T16:28:37+00:00" + "time": "2017-02-14 16:28:37" }, { "name": "psr/log", @@ -1213,7 +1270,7 @@ "psr", "psr-3" ], - "time": "2016-10-10T12:19:37+00:00" + "time": "2016-10-10 12:19:37" }, { "name": "ramsey/uuid", @@ -1295,7 +1352,7 @@ "identifier", "uuid" ], - "time": "2017-03-26T20:37:53+00:00" + "time": "2017-03-26 20:37:53" }, { "name": "seld/cli-prompt", @@ -1343,7 +1400,7 @@ "input", "prompt" ], - "time": "2017-03-18T11:32:45+00:00" + "time": "2017-03-18 11:32:45" }, { "name": "seld/jsonlint", @@ -1392,7 +1449,7 @@ "parser", "validator" ], - "time": "2018-01-24T12:46:19+00:00" + "time": "2018-01-24 12:46:19" }, { "name": "seld/phar-utils", @@ -1436,41 +1493,48 @@ "keywords": [ "phra" ], - "time": "2015-10-13T18:44:15+00:00" + "time": "2015-10-13 18:44:15" }, { "name": "symfony/console", - "version": "v2.8.34", + "version": "v4.0.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "162ca7d0ea597599967aa63b23418e747da0896b" + "reference": "555c8dbe0ae9e561740451eabdbed2cc554b6a51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/162ca7d0ea597599967aa63b23418e747da0896b", - "reference": "162ca7d0ea597599967aa63b23418e747da0896b", + "url": "https://api.github.com/repos/symfony/console/zipball/555c8dbe0ae9e561740451eabdbed2cc554b6a51", + "reference": "555c8dbe0ae9e561740451eabdbed2cc554b6a51", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/debug": "^2.7.2|~3.0.0", + "php": "^7.1.3", "symfony/polyfill-mbstring": "~1.0" }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, "require-dev": { "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1|~3.0.0", - "symfony/process": "~2.1|~3.0.0" + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" }, "suggest": { "psr/log": "For using the console logger", "symfony/event-dispatcher": "", + "symfony/lock": "", "symfony/process": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1497,88 +1561,34 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-01-29T08:54:45+00:00" - }, - { - "name": "symfony/debug", - "version": "v3.0.9", - "source": { - "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/697c527acd9ea1b2d3efac34d9806bf255278b0a", - "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "psr/log": "~1.0" - }, - "conflict": { - "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" - }, - "require-dev": { - "symfony/class-loader": "~2.8|~3.0", - "symfony/http-kernel": "~2.8|~3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Debug\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Debug Component", - "homepage": "https://symfony.com", - "time": "2016-07-30T07:22:48+00:00" + "time": "2018-02-26 15:55:47" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.34", + "version": "v4.0.6", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "d64be24fc1eba62f9daace8a8918f797fc8e87cc" + "reference": "85eaf6a8ec915487abac52e133efc4a268204428" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d64be24fc1eba62f9daace8a8918f797fc8e87cc", - "reference": "d64be24fc1eba62f9daace8a8918f797fc8e87cc", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/85eaf6a8ec915487abac52e133efc4a268204428", + "reference": "85eaf6a8ec915487abac52e133efc4a268204428", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": "^7.1.3" + }, + "conflict": { + "symfony/dependency-injection": "<3.4" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "^2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.6|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0" + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/stopwatch": "~3.4|~4.0" }, "suggest": { "symfony/dependency-injection": "", @@ -1587,7 +1597,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1614,20 +1624,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:36:31+00:00" + "time": "2018-02-14 14:11:10" }, { "name": "symfony/filesystem", - "version": "v3.4.4", + "version": "v3.4.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "e078773ad6354af38169faf31c21df0f18ace03d" + "reference": "253a4490b528597aa14d2bf5aeded6f5e5e4a541" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/e078773ad6354af38169faf31c21df0f18ace03d", - "reference": "e078773ad6354af38169faf31c21df0f18ace03d", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/253a4490b528597aa14d2bf5aeded6f5e5e4a541", + "reference": "253a4490b528597aa14d2bf5aeded6f5e5e4a541", "shasum": "" }, "require": { @@ -1663,29 +1673,29 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" + "time": "2018-02-22 10:48:49" }, { "name": "symfony/finder", - "version": "v3.4.4", + "version": "v4.0.6", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f" + "reference": "44a796d2ecc2a16a5fc8f2956a34ee617934d55f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/613e26310776f49a1773b6737c6bd554b8bc8c6f", - "reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f", + "url": "https://api.github.com/repos/symfony/finder/zipball/44a796d2ecc2a16a5fc8f2956a34ee617934d55f", + "reference": "44a796d2ecc2a16a5fc8f2956a34ee617934d55f", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": "^7.1.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1712,7 +1722,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" + "time": "2018-03-05 18:28:26" }, { "name": "symfony/polyfill-mbstring", @@ -1771,29 +1781,29 @@ "portable", "shim" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-01-30 19:27:44" }, { "name": "symfony/process", - "version": "v2.8.34", + "version": "v4.0.6", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "905efe90024caa75a2fc93f54e14b26f2a099d96" + "reference": "6ed08502a7c9559da8e60ea343bdbd19c3350b3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/905efe90024caa75a2fc93f54e14b26f2a099d96", - "reference": "905efe90024caa75a2fc93f54e14b26f2a099d96", + "url": "https://api.github.com/repos/symfony/process/zipball/6ed08502a7c9559da8e60ea343bdbd19c3350b3e", + "reference": "6ed08502a7c9559da8e60ea343bdbd19c3350b3e", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": "^7.1.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1820,7 +1830,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-01-29T08:54:45+00:00" + "time": "2018-02-19 12:18:43" }, { "name": "tedivm/jshrink", @@ -1866,7 +1876,7 @@ "javascript", "minifier" ], - "time": "2015-07-04T07:35:09+00:00" + "time": "2015-07-04 07:35:09" }, { "name": "tubalmartin/cssmin", @@ -1919,7 +1929,7 @@ "minify", "yui" ], - "time": "2017-05-16T13:45:26+00:00" + "time": "2017-05-16 13:45:26" }, { "name": "webonyx/graphql-php", @@ -1966,7 +1976,7 @@ "api", "graphql" ], - "time": "2017-12-12T09:03:21+00:00" + "time": "2017-12-12 09:03:21" }, { "name": "zendframework/zend-captcha", @@ -2023,7 +2033,7 @@ "captcha", "zf2" ], - "time": "2017-02-23T08:09:44+00:00" + "time": "2017-02-23 08:09:44" }, { "name": "zendframework/zend-code", @@ -2076,7 +2086,7 @@ "code", "zf2" ], - "time": "2016-10-24T13:23:32+00:00" + "time": "2016-10-24 13:23:32" }, { "name": "zendframework/zend-config", @@ -2132,7 +2142,7 @@ "config", "zf2" ], - "time": "2016-02-04T23:01:10+00:00" + "time": "2016-02-04 23:01:10" }, { "name": "zendframework/zend-console", @@ -2185,7 +2195,7 @@ "console", "zf" ], - "time": "2018-01-25T19:08:04+00:00" + "time": "2018-01-25 19:08:04" }, { "name": "zendframework/zend-crypt", @@ -2235,7 +2245,7 @@ "crypt", "zf2" ], - "time": "2016-02-03T23:46:30+00:00" + "time": "2016-02-03 23:46:30" }, { "name": "zendframework/zend-db", @@ -2293,7 +2303,7 @@ "db", "zf" ], - "time": "2017-12-11T14:57:52+00:00" + "time": "2017-12-11 14:57:52" }, { "name": "zendframework/zend-di", @@ -2340,7 +2350,7 @@ "di", "zf2" ], - "time": "2016-04-25T20:58:11+00:00" + "time": "2016-04-25 20:58:11" }, { "name": "zendframework/zend-escaper", @@ -2384,7 +2394,7 @@ "escaper", "zf2" ], - "time": "2016-06-30T19:48:38+00:00" + "time": "2016-06-30 19:48:38" }, { "name": "zendframework/zend-eventmanager", @@ -2431,7 +2441,7 @@ "eventmanager", "zf2" ], - "time": "2017-12-12T17:48:56+00:00" + "time": "2017-12-12 17:48:56" }, { "name": "zendframework/zend-feed", @@ -2492,7 +2502,7 @@ "feed", "zf" ], - "time": "2017-12-04T17:59:38+00:00" + "time": "2017-12-04 17:59:38" }, { "name": "zendframework/zend-filter", @@ -2552,7 +2562,7 @@ "filter", "zf2" ], - "time": "2017-05-17T20:56:17+00:00" + "time": "2017-05-17 20:56:17" }, { "name": "zendframework/zend-form", @@ -2630,7 +2640,7 @@ "form", "zf" ], - "time": "2017-12-06T21:09:08+00:00" + "time": "2017-12-06 21:09:08" }, { "name": "zendframework/zend-http", @@ -2683,7 +2693,7 @@ "zend", "zf" ], - "time": "2017-10-13T12:06:24+00:00" + "time": "2017-10-13 12:06:24" }, { "name": "zendframework/zend-hydrator", @@ -2741,7 +2751,7 @@ "hydrator", "zf2" ], - "time": "2016-02-18T22:38:26+00:00" + "time": "2016-02-18 22:38:26" }, { "name": "zendframework/zend-i18n", @@ -2808,7 +2818,7 @@ "i18n", "zf2" ], - "time": "2017-05-17T17:00:12+00:00" + "time": "2017-05-17 17:00:12" }, { "name": "zendframework/zend-inputfilter", @@ -2861,7 +2871,7 @@ "inputfilter", "zf" ], - "time": "2018-01-22T19:41:18+00:00" + "time": "2018-01-22 19:41:18" }, { "name": "zendframework/zend-json", @@ -2916,7 +2926,7 @@ "json", "zf2" ], - "time": "2016-02-04T21:20:26+00:00" + "time": "2016-02-04 21:20:26" }, { "name": "zendframework/zend-loader", @@ -2960,7 +2970,7 @@ "loader", "zf2" ], - "time": "2015-06-03T14:05:47+00:00" + "time": "2015-06-03 14:05:47" }, { "name": "zendframework/zend-log", @@ -3031,29 +3041,29 @@ "logging", "zf2" ], - "time": "2017-05-17T16:03:26+00:00" + "time": "2017-05-17 16:03:26" }, { "name": "zendframework/zend-mail", - "version": "2.8.0", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-mail.git", - "reference": "248230940ab1453b2a532a8fde76c5a6470d7aad" + "reference": "067248425f285dec0bdb74256a8f67f9092f115e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-mail/zipball/248230940ab1453b2a532a8fde76c5a6470d7aad", - "reference": "248230940ab1453b2a532a8fde76c5a6470d7aad", + "url": "https://api.github.com/repos/zendframework/zend-mail/zipball/067248425f285dec0bdb74256a8f67f9092f115e", + "reference": "067248425f285dec0bdb74256a8f67f9092f115e", "shasum": "" }, "require": { "ext-iconv": "*", - "php": "^7.0 || ^5.6", + "php": "^7.1", "zendframework/zend-loader": "^2.5", "zendframework/zend-mime": "^2.5", "zendframework/zend-stdlib": "^2.7 || ^3.0", - "zendframework/zend-validator": "^2.6" + "zendframework/zend-validator": "^2.10.2" }, "require-dev": { "phpunit/phpunit": "^6.0.8 || ^5.7.15", @@ -3093,7 +3103,7 @@ "mail", "zf2" ], - "time": "2017-06-08T20:03:58+00:00" + "time": "2018-03-01 18:57:00" }, { "name": "zendframework/zend-math", @@ -3143,7 +3153,7 @@ "math", "zf2" ], - "time": "2016-04-07T16:29:53+00:00" + "time": "2016-04-07 16:29:53" }, { "name": "zendframework/zend-mime", @@ -3194,7 +3204,7 @@ "mime", "zf" ], - "time": "2017-11-28T15:02:22+00:00" + "time": "2017-11-28 15:02:22" }, { "name": "zendframework/zend-modulemanager", @@ -3254,7 +3264,7 @@ "modulemanager", "zf" ], - "time": "2017-12-02T06:11:18+00:00" + "time": "2017-12-02 06:11:18" }, { "name": "zendframework/zend-mvc", @@ -3341,7 +3351,7 @@ "mvc", "zf2" ], - "time": "2016-02-23T15:24:59+00:00" + "time": "2016-02-23 15:24:59" }, { "name": "zendframework/zend-serializer", @@ -3399,7 +3409,7 @@ "serializer", "zf2" ], - "time": "2017-11-20T22:21:04+00:00" + "time": "2017-11-20 22:21:04" }, { "name": "zendframework/zend-server", @@ -3445,7 +3455,7 @@ "server", "zf2" ], - "time": "2016-06-20T22:27:55+00:00" + "time": "2016-06-20 22:27:55" }, { "name": "zendframework/zend-servicemanager", @@ -3497,20 +3507,20 @@ "servicemanager", "zf2" ], - "time": "2017-12-05T16:27:36+00:00" + "time": "2017-12-05 16:27:36" }, { "name": "zendframework/zend-session", - "version": "2.8.4", + "version": "2.8.5", "source": { "type": "git", "url": "https://github.com/zendframework/zend-session.git", - "reference": "9338f1ae483bcc18cc3b6c0347c8ba4f448b3e2a" + "reference": "2cfd90e1a2f6b066b9f908599251d8f64f07021b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-session/zipball/9338f1ae483bcc18cc3b6c0347c8ba4f448b3e2a", - "reference": "9338f1ae483bcc18cc3b6c0347c8ba4f448b3e2a", + "url": "https://api.github.com/repos/zendframework/zend-session/zipball/2cfd90e1a2f6b066b9f908599251d8f64f07021b", + "reference": "2cfd90e1a2f6b066b9f908599251d8f64f07021b", "shasum": "" }, "require": { @@ -3518,14 +3528,11 @@ "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", "zendframework/zend-stdlib": "^2.7 || ^3.0" }, - "conflict": { - "phpunit/phpunit": ">=6.5.0" - }, "require-dev": { "container-interop/container-interop": "^1.1", "mongodb/mongodb": "^1.0.1", "php-mock/php-mock-phpunit": "^1.1.2 || ^2.0", - "phpunit/phpunit": "^5.7.5 || ^6.0.13", + "phpunit/phpunit": "^5.7.5 || >=6.0.13 <6.5.0", "zendframework/zend-cache": "^2.6.1", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-db": "^2.7", @@ -3567,7 +3574,7 @@ "session", "zf" ], - "time": "2018-01-31T17:38:47+00:00" + "time": "2018-02-22 16:33:54" }, { "name": "zendframework/zend-soap", @@ -3620,7 +3627,7 @@ "soap", "zf2" ], - "time": "2018-01-29T17:51:26+00:00" + "time": "2018-01-29 17:51:26" }, { "name": "zendframework/zend-stdlib", @@ -3679,7 +3686,7 @@ "stdlib", "zf2" ], - "time": "2016-04-12T21:17:31+00:00" + "time": "2016-04-12 21:17:31" }, { "name": "zendframework/zend-text", @@ -3726,7 +3733,7 @@ "text", "zf2" ], - "time": "2016-02-08T19:03:52+00:00" + "time": "2016-02-08 19:03:52" }, { "name": "zendframework/zend-uri", @@ -3773,7 +3780,7 @@ "uri", "zf2" ], - "time": "2016-02-17T22:38:51+00:00" + "time": "2016-02-17 22:38:51" }, { "name": "zendframework/zend-validator", @@ -3844,7 +3851,7 @@ "validator", "zf2" ], - "time": "2018-02-01T17:05:33+00:00" + "time": "2018-02-01 17:05:33" }, { "name": "zendframework/zend-view", @@ -3931,38 +3938,106 @@ "view", "zf2" ], - "time": "2018-01-17T22:21:50+00:00" + "time": "2018-01-17 22:21:50" } ], "packages-dev": [ + { + "name": "doctrine/annotations", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", + "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": "^7.1" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2017-12-06 07:11:42" + }, { "name": "doctrine/instantiator", - "version": "1.0.5", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", "shasum": "" }, "require": { - "php": ">=5.3,<8.0-DEV" + "php": "^7.1" }, "require-dev": { "athletic/athletic": "~0.1.8", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" + "phpunit/phpunit": "^6.2.3", + "squizlabs/php_codesniffer": "^3.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -3987,59 +4062,34 @@ "constructor", "instantiate" ], - "time": "2015-06-14T21:17:01+00:00" + "time": "2017-07-22 11:58:36" }, { - "name": "friendsofphp/php-cs-fixer", - "version": "v2.1.3", + "name": "doctrine/lexer", + "version": "v1.0.1", "source": { "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "d30ca69f8bed931b5c630407f0a98306e33c2c39" + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/d30ca69f8bed931b5c630407f0a98306e33c2c39", - "reference": "d30ca69f8bed931b5c630407f0a98306e33c2c39", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": "^5.3.6 || >=7.0 <7.2", - "sebastian/diff": "^1.1", - "symfony/console": "^2.3 || ^3.0", - "symfony/event-dispatcher": "^2.1 || ^3.0", - "symfony/filesystem": "^2.4 || ^3.0", - "symfony/finder": "^2.2 || ^3.0", - "symfony/polyfill-php54": "^1.0", - "symfony/polyfill-php55": "^1.3", - "symfony/polyfill-php70": "^1.0", - "symfony/polyfill-xml": "^1.3", - "symfony/process": "^2.3 || ^3.0", - "symfony/stopwatch": "^2.5 || ^3.0" - }, - "conflict": { - "hhvm": "<3.9" - }, - "require-dev": { - "gecko-packages/gecko-php-unit": "^2.0", - "justinrainbow/json-schema": "^5.0", - "phpunit/phpunit": "^4.5 || ^5.0", - "satooshi/php-coveralls": "^1.0", - "symfony/phpunit-bridge": "^3.2" + "php": ">=5.3.2" }, - "suggest": { - "ext-mbstring": "For handling non-UTF8 characters in cache singature.", - "ext-xml": "For better performance.", - "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } }, - "bin": [ - "php-cs-fixer" - ], - "type": "application", "autoload": { - "psr-4": { - "PhpCsFixer\\": "src/" + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", @@ -4048,38 +4098,94 @@ ], "authors": [ { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" + "name": "Roman Borschel", + "email": "roman@code-factory.org" }, { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" } ], - "description": "A tool to automatically fix PHP code style", - "time": "2017-03-31T12:59:38+00:00" + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09 13:34:57" }, { - "name": "ircmaxell/password-compat", - "version": "v1.0.4", + "name": "friendsofphp/php-cs-fixer", + "version": "v2.10.4", "source": { "type": "git", - "url": "https://github.com/ircmaxell/password_compat.git", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" + "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", + "reference": "b2dce1dacff988b79c4aadf252e5dee31bc04e19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/b2dce1dacff988b79c4aadf252e5dee31bc04e19", + "reference": "b2dce1dacff988b79c4aadf252e5dee31bc04e19", "shasum": "" }, + "require": { + "composer/semver": "^1.4", + "doctrine/annotations": "^1.2", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^5.6 || >=7.0 <7.3", + "php-cs-fixer/diff": "^1.2", + "symfony/console": "^3.2 || ^4.0", + "symfony/event-dispatcher": "^3.0 || ^4.0", + "symfony/filesystem": "^3.0 || ^4.0", + "symfony/finder": "^3.0 || ^4.0", + "symfony/options-resolver": "^3.0 || ^4.0", + "symfony/polyfill-php70": "^1.0", + "symfony/polyfill-php72": "^1.4", + "symfony/process": "^3.0 || ^4.0", + "symfony/stopwatch": "^3.0 || ^4.0" + }, + "conflict": { + "hhvm": "*" + }, "require-dev": { - "phpunit/phpunit": "4.*" + "johnkary/phpunit-speedtrap": "^1.1 || ^2.0 || ^3.0", + "justinrainbow/json-schema": "^5.0", + "keradus/cli-executor": "^1.0", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.0", + "php-cs-fixer/accessible-object": "^1.0", + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "phpunitgoodpractices/traits": "^1.3.1", + "symfony/phpunit-bridge": "^3.2.2 || ^4.0" }, - "type": "library", + "suggest": { + "ext-mbstring": "For handling non-UTF8 characters in cache signature.", + "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", "autoload": { - "files": [ - "lib/password.php" + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "classmap": [ + "tests/Test/AbstractFixerTestCase.php", + "tests/Test/AbstractIntegrationCaseFactory.php", + "tests/Test/AbstractIntegrationTestCase.php", + "tests/Test/Assert/AssertTokensTrait.php", + "tests/Test/Constraint/SameStringsConstraint.php", + "tests/Test/IntegrationCase.php", + "tests/Test/IntegrationCaseFactory.php", + "tests/Test/IntegrationCaseFactoryInterface.php", + "tests/Test/InternalIntegrationCaseFactory.php", + "tests/TestCase.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -4088,18 +4194,16 @@ ], "authors": [ { - "name": "Anthony Ferrara", - "email": "ircmaxell@php.net", - "homepage": "http://blog.ircmaxell.com" + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" } ], - "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", - "homepage": "https://github.com/ircmaxell/password_compat", - "keywords": [ - "hashing", - "password" - ], - "time": "2014-11-20T16:49:30+00:00" + "description": "A tool to automatically fix PHP code style", + "time": "2018-03-08 11:13:12" }, { "name": "lusitanian/oauth", @@ -4166,7 +4270,7 @@ "oauth", "security" ], - "time": "2016-07-12T22:15:40+00:00" + "time": "2016-07-12 22:15:40" }, { "name": "myclabs/deep-copy", @@ -4211,7 +4315,7 @@ "object", "object graph" ], - "time": "2017-10-19T19:58:43+00:00" + "time": "2017-10-19 19:58:43" }, { "name": "pdepend/pdepend", @@ -4251,7 +4355,7 @@ "BSD-3-Clause" ], "description": "Official version of pdepend to be handled with Composer", - "time": "2017-01-19T14:23:36+00:00" + "time": "2017-01-19 14:23:36" }, { "name": "phar-io/manifest", @@ -4306,7 +4410,7 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" + "time": "2017-03-05 18:14:27" }, { "name": "phar-io/version", @@ -4353,7 +4457,58 @@ } ], "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" + "time": "2017-03-05 17:38:23" + }, + { + "name": "php-cs-fixer/diff", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/diff.git", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/78bb099e9c16361126c86ce82ec4405ebab8e756", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "symfony/process": "^3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "SpacePossum" + } + ], + "description": "sebastian/diff v2 backport support for PHP5.6", + "homepage": "https://github.com/PHP-CS-Fixer", + "keywords": [ + "diff" + ], + "time": "2018-02-15 16:58:55" }, { "name": "phpdocumentor/reflection-common", @@ -4407,7 +4562,7 @@ "reflection", "static analysis" ], - "time": "2017-09-11T18:02:19+00:00" + "time": "2017-09-11 18:02:19" }, { "name": "phpdocumentor/reflection-docblock", @@ -4458,7 +4613,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-30T07:14:17+00:00" + "time": "2017-11-30 07:14:17" }, { "name": "phpdocumentor/type-resolver", @@ -4505,7 +4660,7 @@ "email": "me@mikevanriel.com" } ], - "time": "2017-07-14T14:27:02+00:00" + "time": "2017-07-14 14:27:02" }, { "name": "phpmd/phpmd", @@ -4571,20 +4726,20 @@ "phpmd", "pmd" ], - "time": "2017-01-20T14:41:10+00:00" + "time": "2017-01-20 14:41:10" }, { "name": "phpspec/prophecy", - "version": "1.7.3", + "version": "1.7.5", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf" + "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", - "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/dfd6be44111a7c41c2e884a336cc4f461b3b2401", + "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401", "shasum": "" }, "require": { @@ -4596,7 +4751,7 @@ }, "require-dev": { "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" }, "type": "library", "extra": { @@ -4634,7 +4789,7 @@ "spy", "stub" ], - "time": "2017-11-24T13:59:53+00:00" + "time": "2018-02-19 10:16:54" }, { "name": "phpunit/php-code-coverage", @@ -4697,7 +4852,7 @@ "testing", "xunit" ], - "time": "2017-12-06T09:29:45+00:00" + "time": "2017-12-06 09:29:45" }, { "name": "phpunit/php-file-iterator", @@ -4744,7 +4899,7 @@ "filesystem", "iterator" ], - "time": "2017-11-27T13:52:08+00:00" + "time": "2017-11-27 13:52:08" }, { "name": "phpunit/php-text-template", @@ -4785,7 +4940,7 @@ "keywords": [ "template" ], - "time": "2015-06-21T13:50:34+00:00" + "time": "2015-06-21 13:50:34" }, { "name": "phpunit/php-timer", @@ -4834,7 +4989,7 @@ "keywords": [ "timer" ], - "time": "2017-02-26T11:10:40+00:00" + "time": "2017-02-26 11:10:40" }, { "name": "phpunit/php-token-stream", @@ -4883,7 +5038,7 @@ "keywords": [ "tokenizer" ], - "time": "2017-11-27T05:48:46+00:00" + "time": "2017-11-27 05:48:46" }, { "name": "phpunit/phpunit", @@ -4967,7 +5122,7 @@ "testing", "xunit" ], - "time": "2017-08-03T13:59:28+00:00" + "time": "2017-08-03 13:59:28" }, { "name": "phpunit/phpunit-mock-objects", @@ -5026,7 +5181,7 @@ "mock", "xunit" ], - "time": "2017-08-03T14:08:16+00:00" + "time": "2017-08-03 14:08:16" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -5071,7 +5226,7 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" + "time": "2017-03-04 06:30:41" }, { "name": "sebastian/comparator", @@ -5135,7 +5290,7 @@ "compare", "equality" ], - "time": "2017-03-03T06:26:08+00:00" + "time": "2017-03-03 06:26:08" }, { "name": "sebastian/diff", @@ -5187,7 +5342,7 @@ "keywords": [ "diff" ], - "time": "2017-05-22T07:24:03+00:00" + "time": "2017-05-22 07:24:03" }, { "name": "sebastian/environment", @@ -5237,7 +5392,7 @@ "environment", "hhvm" ], - "time": "2017-07-01T08:51:00+00:00" + "time": "2017-07-01 08:51:00" }, { "name": "sebastian/exporter", @@ -5304,7 +5459,7 @@ "export", "exporter" ], - "time": "2017-04-03T13:19:02+00:00" + "time": "2017-04-03 13:19:02" }, { "name": "sebastian/finder-facade", @@ -5343,7 +5498,7 @@ ], "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", "homepage": "https://github.com/sebastianbergmann/finder-facade", - "time": "2017-11-18T17:31:49+00:00" + "time": "2017-11-18 17:31:49" }, { "name": "sebastian/global-state", @@ -5394,7 +5549,7 @@ "keywords": [ "global state" ], - "time": "2017-04-27T15:39:26+00:00" + "time": "2017-04-27 15:39:26" }, { "name": "sebastian/object-enumerator", @@ -5441,7 +5596,7 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" + "time": "2017-08-03 12:35:26" }, { "name": "sebastian/object-reflector", @@ -5486,29 +5641,28 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" + "time": "2017-03-29 09:07:27" }, { "name": "sebastian/phpcpd", - "version": "2.0.4", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpcpd.git", - "reference": "24d9a880deadb0b8c9680e9cfe78e30b704225db" + "reference": "dfed51c1288790fc957c9433e2f49ab152e8a564" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/24d9a880deadb0b8c9680e9cfe78e30b704225db", - "reference": "24d9a880deadb0b8c9680e9cfe78e30b704225db", + "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/dfed51c1288790fc957c9433e2f49ab152e8a564", + "reference": "dfed51c1288790fc957c9433e2f49ab152e8a564", "shasum": "" }, "require": { - "php": ">=5.3.3", - "phpunit/php-timer": ">=1.0.6", - "sebastian/finder-facade": "~1.1", - "sebastian/version": "~1.0|~2.0", - "symfony/console": "~2.7|^3.0", - "theseer/fdomdocument": "~1.4" + "php": "^5.6|^7.0", + "phpunit/php-timer": "^1.0.6", + "sebastian/finder-facade": "^1.1", + "sebastian/version": "^1.0|^2.0", + "symfony/console": "^2.7|^3.0|^4.0" }, "bin": [ "phpcpd" @@ -5516,7 +5670,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -5537,7 +5691,7 @@ ], "description": "Copy/Paste Detector (CPD) for PHP code.", "homepage": "https://github.com/sebastianbergmann/phpcpd", - "time": "2016-04-17T19:32:49+00:00" + "time": "2017-11-16 08:49:28" }, { "name": "sebastian/recursion-context", @@ -5590,7 +5744,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" + "time": "2017-03-03 06:23:57" }, { "name": "sebastian/resource-operations", @@ -5632,7 +5786,7 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" + "time": "2015-07-28 20:34:47" }, { "name": "sebastian/version", @@ -5675,7 +5829,7 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" + "time": "2016-10-03 07:35:21" }, { "name": "squizlabs/php_codesniffer", @@ -5726,20 +5880,20 @@ "phpcs", "standards" ], - "time": "2017-06-14T01:23:49+00:00" + "time": "2017-06-14 01:23:49" }, { "name": "symfony/config", - "version": "v3.4.4", + "version": "v3.4.6", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "72689b934d6c6ecf73eca874e98933bf055313c9" + "reference": "05e10567b529476a006b00746c5f538f1636810e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/72689b934d6c6ecf73eca874e98933bf055313c9", - "reference": "72689b934d6c6ecf73eca874e98933bf055313c9", + "url": "https://api.github.com/repos/symfony/config/zipball/05e10567b529476a006b00746c5f538f1636810e", + "reference": "05e10567b529476a006b00746c5f538f1636810e", "shasum": "" }, "require": { @@ -5752,6 +5906,7 @@ }, "require-dev": { "symfony/dependency-injection": "~3.3|~4.0", + "symfony/event-dispatcher": "~3.3|~4.0", "symfony/finder": "~3.3|~4.0", "symfony/yaml": "~3.0|~4.0" }, @@ -5788,20 +5943,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2018-01-21T19:05:02+00:00" + "time": "2018-02-14 10:03:57" }, { "name": "symfony/dependency-injection", - "version": "v3.4.4", + "version": "v3.4.6", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "4b2717ee2499390e371e1fc7abaf886c1c83e83d" + "reference": "12e901abc1cb0d637a0e5abe9923471361d96b07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/4b2717ee2499390e371e1fc7abaf886c1c83e83d", - "reference": "4b2717ee2499390e371e1fc7abaf886c1c83e83d", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/12e901abc1cb0d637a0e5abe9923471361d96b07", + "reference": "12e901abc1cb0d637a0e5abe9923471361d96b07", "shasum": "" }, "require": { @@ -5859,96 +6014,37 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2018-01-29T09:16:57+00:00" + "time": "2018-03-04 03:54:53" }, { - "name": "symfony/polyfill-php54", - "version": "v1.7.0", + "name": "symfony/options-resolver", + "version": "v4.0.6", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php54.git", - "reference": "84e2b616c197ef400c6d0556a0606cee7c9e21d5" + "url": "https://github.com/symfony/options-resolver.git", + "reference": "371532a2cfe932f7a3766dd4c45364566def1dd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/84e2b616c197ef400c6d0556a0606cee7c9e21d5", - "reference": "84e2b616c197ef400c6d0556a0606cee7c9e21d5", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/371532a2cfe932f7a3766dd4c45364566def1dd0", + "reference": "371532a2cfe932f7a3766dd4c45364566def1dd0", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.1.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7-dev" + "dev-master": "4.0-dev" } }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Php54\\": "" + "Symfony\\Component\\OptionsResolver\\": "" }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-30T19:27:44+00:00" - }, - { - "name": "symfony/polyfill-php55", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php55.git", - "reference": "168371cb3dfb10e0afde96e7c2688be02470d143" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/168371cb3dfb10e0afde96e7c2688be02470d143", - "reference": "168371cb3dfb10e0afde96e7c2688be02470d143", - "shasum": "" - }, - "require": { - "ircmaxell/password-compat": "~1.0", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php55\\": "" - }, - "files": [ - "bootstrap.php" + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -5957,23 +6053,22 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", + "description": "Symfony OptionsResolver Component", "homepage": "https://symfony.com", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "config", + "configuration", + "options" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-01-18 22:19:33" }, { "name": "symfony/polyfill-php70", @@ -6032,7 +6127,7 @@ "portable", "shim" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-01-30 19:27:44" }, { "name": "symfony/polyfill-php72", @@ -6087,77 +6182,29 @@ "portable", "shim" ], - "time": "2018-01-31T17:43:24+00:00" - }, - { - "name": "symfony/polyfill-xml", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-xml.git", - "reference": "fcdfb6e64d21848ee65b6d5d0bc75fcb703b0c83" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-xml/zipball/fcdfb6e64d21848ee65b6d5d0bc75fcb703b0c83", - "reference": "fcdfb6e64d21848ee65b6d5d0bc75fcb703b0c83", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/polyfill-php72": "~1.4" - }, - "type": "metapackage", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for xml's utf8_encode and utf8_decode functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-01-31 17:43:24" }, { "name": "symfony/stopwatch", - "version": "v3.4.4", + "version": "v4.0.6", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "c865551df7c17e63fc1f09f763db04387f91ae4d" + "reference": "6795ffa2f8eebedac77f045aa62c0c10b2763042" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/c865551df7c17e63fc1f09f763db04387f91ae4d", - "reference": "c865551df7c17e63fc1f09f763db04387f91ae4d", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/6795ffa2f8eebedac77f045aa62c0c10b2763042", + "reference": "6795ffa2f8eebedac77f045aa62c0c10b2763042", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": "^7.1.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -6184,7 +6231,7 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" + "time": "2018-02-19 16:50:22" }, { "name": "theseer/fdomdocument", @@ -6224,7 +6271,7 @@ ], "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", "homepage": "https://github.com/theseer/fDOMDocument", - "time": "2017-06-30T11:53:12+00:00" + "time": "2017-06-30 11:53:12" }, { "name": "theseer/tokenizer", @@ -6264,7 +6311,7 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2017-04-07T12:08:54+00:00" + "time": "2017-04-07 12:08:54" }, { "name": "webmozart/assert", @@ -6314,18 +6361,20 @@ "check", "validate" ], - "time": "2018-01-29T19:49:41+00:00" + "time": "2018-01-29 19:49:41" } ], "aliases": [], "minimum-stability": "stable", "stability-flags": { + "magento/composer": 20, + "magento/zendframework1": 20, "phpmd/phpmd": 0 }, "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", @@ -6334,7 +6383,6 @@ "ext-iconv": "*", "ext-intl": "*", "ext-mbstring": "*", - "ext-mcrypt": "*", "ext-openssl": "*", "ext-pdo_mysql": "*", "ext-simplexml": "*", From d29306ccc7f4ef8f70706b57481d254f3e1c033b Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 16 Mar 2018 18:08:02 -0500 Subject: [PATCH 096/668] MAGETWO-89292: Implement SDL from prototype - decompose --- app/code/Magento/GraphQl/etc/di.xml | 10 + .../GraphQl/Config/GraphQlReader.php | 305 ++---------------- .../MetaReader/FieldMetaReader.php | 82 +++++ .../MetaReader/TypeMetaReader.php | 61 ++++ .../Config/GraphQlReader/Reader/EnumType.php | 38 +++ .../GraphQlReader/Reader/InputObjectType.php | 68 ++++ .../GraphQlReader/Reader/InterfaceType.php | 78 +++++ .../GraphQlReader/Reader/ObjectType.php | 61 ++++ .../GraphQlReader/TypeMetaReaderInterface.php | 19 ++ .../Config/GraphQlReader/TypeReader.php | 37 +++ 10 files changed, 485 insertions(+), 274 deletions(-) create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/TypeMetaReaderInterface.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/TypeReader.php diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 6060fe9102188..49b1393141df0 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -121,4 +121,14 @@ </argument> </arguments> </type> + <type name="Magento\Framework\GraphQl\Config\GraphQlReader\TypeReader"> + <arguments> + <argument name="typeReaders" xsi:type="array"> + <item name="enum_type" xsi:type="object">Magento\Framework\GraphQl\Config\GraphQlReader\Reader\EnumType</item> + <item name="object_type" xsi:type="object">Magento\Framework\GraphQl\Config\GraphQlReader\Reader\ObjectType</item> + <item name="input_object" xsi:type="object">Magento\Framework\GraphQl\Config\GraphQlReader\Reader\InputObjectType</item> + <item name="interface_type" xsi:type="object">Magento\Framework\GraphQl\Config\GraphQlReader\Reader\InterfaceType</item> + </argument> + </arguments> + </type> </config> diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php index 3b4c100f584ae..be5d048cb020f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php @@ -7,14 +7,23 @@ namespace Magento\Framework\GraphQl\Config; +use Magento\Framework\Config\FileResolverInterface; +use Magento\Framework\GraphQl\Config\GraphQlReader\TypeReader; + class GraphQlReader implements \Magento\Framework\Config\ReaderInterface { /** * File locator * - * @var \Magento\Framework\Config\FileResolverInterface + * @var FileResolverInterface */ - protected $fileResolver; + private $fileResolver; + + /** + * @var TypeReader + */ + private $typeReader; + /** * @var string @@ -24,14 +33,22 @@ class GraphQlReader implements \Magento\Framework\Config\ReaderInterface /** * @var string */ - protected $defaultScope; + private $defaultScope; + /** + * @param FileResolverInterface $fileResolver + * @param TypeReader $typeReader + * @param string $fileName + * @param string $defaultScope + */ public function __construct( - \Magento\Framework\Config\FileResolverInterface $fileResolver, + FileResolverInterface $fileResolver, + TypeReader $typeReader, $fileName = 'schema.graphql', $defaultScope = 'global' ) { $this->fileResolver = $fileResolver; + $this->typeReader = $typeReader; $this->defaultScope = $defaultScope; $this->fileName = $fileName; } @@ -46,7 +63,7 @@ public function read($scope = null) : array } /** - * Compatible with @see \Magento\Framework\GraphQl\Config\GraphQlReader::parseTypes + * Compatible with @see GraphQlReader::parseTypes */ $knownTypes = []; foreach ($schemaFiles as $partialSchemaContent) { @@ -60,286 +77,26 @@ public function read($scope = null) : array $schema = \GraphQL\Utils\BuildSchema::build($schemaContent); $typeMap = $schema->getTypeMap(); foreach ($typeMap as $typeName => $typeMeta) { - if (strpos($typeName, '__') === 0) { + if ((strpos($typeName, '__') !== 0 && (!$typeMeta instanceof \GraphQL\Type\Definition\ScalarType))) { // Skip built-in object types - continue; - } - - if ($typeMeta instanceof \GraphQL\Type\Definition\ScalarType) { - // Skip built-in scalar types - continue; - } - - // TODO: Use polymorphism instead - if ($typeMeta instanceof \GraphQL\Type\Definition\EnumType) { - $partialResult[$typeName] = $this->readEnumTypeMeta($typeMeta); - continue; - } - if ($typeMeta instanceof \GraphQL\Type\Definition\ObjectType) { - $partialResult[$typeName] = $this->readObjectTypeMeta($typeMeta); - continue; - } - if ($typeMeta instanceof \GraphQL\Type\Definition\InputObjectType) { - $partialResult[$typeName] = $this->readInputObjectTypeMeta($typeMeta); - continue; - } - if ($typeMeta instanceof \GraphQL\Type\Definition\InterfaceType) { - $partialResult[$typeName] = $this->readInterfaceTypeMeta($typeMeta); - continue; + $partialResult[$typeName] = $this->typeReader->read($typeMeta); + if (!$partialResult[$typeName]) { + throw new \LogicException("'{$typeName}' cannot be processed."); + } } - // TODO: This is necessary to catch unprocessed GraphQL types, like unions if the will be used in schema - throw new \LogicException("'{$typeName}' cannot be processed."); } - $result = array_replace_recursive($result, $partialResult); - } - - return $result; - } - - - /** - * @param \GraphQL\Type\Definition\EnumType $typeMeta - * @return array - */ - private function readEnumTypeMeta(\GraphQL\Type\Definition\EnumType $typeMeta) : array - { - $result = [ - 'name' => $typeMeta->name, - 'type' => 'graphql_enum', - 'items' => [] // Populated later - ]; - foreach ($typeMeta->getValues() as $value) { - // TODO: Simplify structure, currently name is lost during conversion to GraphQL schema - $result['items'][$value->value] = [ - 'name' => strtolower($value->name), - '_value' => $value->value - ]; - } - - return $result; - } - - /** - * @param string $type - * @return bool - */ - private function isScalarType(string $type) : bool - { - return in_array($type, ['String', 'Int', 'Float', 'Boolean', 'ID']); - } - - /** - * @param \GraphQL\Type\Definition\ObjectType $typeMeta - * @return array - */ - private function readObjectTypeMeta(\GraphQL\Type\Definition\ObjectType $typeMeta) : array - { - $typeName = $typeMeta->name; - $result = [ - 'name' => $typeName, - 'type' => 'graphql_type', - 'fields' => [], // Populated later - - ]; - - $interfaces = $typeMeta->getInterfaces(); - foreach ($interfaces as $interfaceMeta) { - $interfaceName = $interfaceMeta->name; - $result['implements'][$interfaceName] = [ - 'interface' => $interfaceName, - 'copyFields' => true // TODO: Configure in separate config - ]; - } - - $fields = $typeMeta->getFields(); - foreach ($fields as $fieldName => $fieldMeta) { - $result['fields'][$fieldName] = $this->readFieldMeta($fieldMeta); - } - - return $result; - } - - /** - * @param \GraphQL\Type\Definition\InputObjectType $typeMeta - * @return array - */ - private function readInputObjectTypeMeta(\GraphQL\Type\Definition\InputObjectType $typeMeta) : array - { - $typeName = $typeMeta->name; - $result = [ - 'name' => $typeName, - 'type' => 'graphql_input', - 'fields' => [] // Populated later - ]; - $fields = $typeMeta->getFields(); - foreach ($fields as $fieldName => $fieldMeta) { - $result['fields'][$fieldName] = $this->readInputObjectFieldMeta($fieldMeta); - } - return $result; - } - - /** - * @param \GraphQL\Type\Definition\InterfaceType $typeMeta - * @return array - */ - private function readInterfaceTypeMeta(\GraphQL\Type\Definition\InterfaceType $typeMeta) : array - { - $typeName = $typeMeta->name; - $result = [ - 'name' => $typeName, - 'type' => 'graphql_interface', - 'fields' => [] - ]; - - $interfaceTypeResolver = $this->readInterfaceTypeResolver($typeMeta); - if ($interfaceTypeResolver) { - $result['typeResolver'] = $interfaceTypeResolver; - } - - $fields = $typeMeta->getFields(); - foreach ($fields as $fieldName => $fieldMeta) { - $result['fields'][$fieldName] = $this->readFieldMeta($fieldMeta); - } - return $result; - } - /** - * @param \GraphQL\Type\Definition\FieldDefinition $fieldMeta - * @return array - */ - private function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) : array - { - $fieldName = $fieldMeta->name; - $fieldTypeMeta = $fieldMeta->getType(); - $result = [ - 'name' => $fieldName, - 'arguments' => [] - ]; - - $fieldResolver = $this->readFieldResolver($fieldMeta); - if ($fieldResolver) { - $result['resolver'] = $fieldResolver; - } - - $result = array_merge( - $result, - $this->readTypeMeta($fieldTypeMeta, 'OutputField') - ); - - $arguments = $fieldMeta->args; - foreach ($arguments as $argumentMeta) { - $argumentName = $argumentMeta->name; - $result['arguments'][$argumentName] = [ - 'name' => $argumentName, - ]; - $typeMeta = $argumentMeta->getType(); - $result['arguments'][$argumentName] = array_merge( - $result['arguments'][$argumentName], - $this->readTypeMeta($typeMeta, 'Argument') - ); + $result = array_replace_recursive($result, $partialResult); } - return $result; - } - - /** - * @param \GraphQL\Type\Definition\InputObjectField $fieldMeta - * @return array - */ - private function readInputObjectFieldMeta(\GraphQL\Type\Definition\InputObjectField $fieldMeta) : array - { - $fieldName = $fieldMeta->name; - $typeMeta = $fieldMeta->getType(); - $result = [ - 'name' => $fieldName, - 'required' => false, - // TODO arguments don't make sense here, but expected to be always present in \Magento\Framework\GraphQl\Config\Data\Mapper\TypeMapper::map - 'arguments' => [] - ]; - - $result = array_merge($result, $this->readTypeMeta($typeMeta, 'InputField')); - return $result; - } - /** - * @param $meta - * @param string $parameterType Argument|OutputField|InputField - * @return array - */ - private function readTypeMeta($meta, $parameterType = 'Argument') : array - { - $result = []; - if ($meta instanceof \GraphQL\Type\Definition\NonNull) { - $result['required'] = true; - $meta = $meta->getWrappedType(); - } else { - $result['required'] = false; - } - if ($meta instanceof \GraphQL\Type\Definition\ListOfType) { - $itemTypeMeta = $meta->ofType; - if ($itemTypeMeta instanceof \GraphQL\Type\Definition\NonNull) { - $result['itemsRequired'] = true; - $itemTypeMeta = $itemTypeMeta->getWrappedType(); - } else { - $result['itemsRequired'] = false; - } - $result['description'] = $itemTypeMeta->description; - $itemTypeName = $itemTypeMeta->name; - $result['itemType'] = $itemTypeName; - if ($this->isScalarType((string)$itemTypeMeta)) { - $result['type'] = 'ScalarArray' . $parameterType; - } else { - $result['type'] = 'ObjectArray' . $parameterType; - } - } else { - $result['description'] = $meta->description; - $result['type'] = $meta->name; - } return $result; } /** - * @param \GraphQL\Type\Definition\FieldDefinition $fieldMeta - * @return string|null - */ - private function readFieldResolver(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) : ?string - { - /** @var \GraphQL\Language\AST\NodeList $directives */ - $directives = $fieldMeta->astNode->directives; - foreach ($directives as $directive) { - if ($directive->name->value == 'resolver') { - foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'class') { - return $directiveArgument->value->value; - } - } - } - } - return null; - } - - /** - * @param \GraphQL\Type\Definition\InterfaceType $interfaceTypeMeta - * @return string|null - */ - private function readInterfaceTypeResolver(\GraphQL\Type\Definition\InterfaceType $interfaceTypeMeta) : ?string - { - /** @var \GraphQL\Language\AST\NodeList $directives */ - $directives = $interfaceTypeMeta->astNode->directives; - foreach ($directives as $directive) { - if ($directive->name->value == 'typeResolver') { - foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'class') { - return $directiveArgument->value->value; - } - } - } - } - return null; - } - - /** + * Extract types as string from a larger string that represents the graphql schema using regular expressions + * * @param string $graphQlSchemaContent - * @return array [$typeName => $typeDeclaration, ...] + * @return string[] [$typeName => $typeDeclaration, ...] */ private function parseTypes($graphQlSchemaContent) : array { diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php new file mode 100644 index 0000000000000..528cdc3f442b8 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php @@ -0,0 +1,82 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader; + +class FieldMetaReader +{ + /** + * @var TypeMetaReader + */ + private $typeMetaReader; + + /** + * @param TypeMetaReader $typeMetaReader + */ + public function __construct(TypeMetaReader $typeMetaReader) + { + $this->typeMetaReader = $typeMetaReader; + } + + /** + * @param \GraphQL\Type\Definition\FieldDefinition $fieldMeta + * @return array + */ + public function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) : array + { + $fieldName = $fieldMeta->name; + $fieldTypeMeta = $fieldMeta->getType(); + $result = [ + 'name' => $fieldName, + 'arguments' => [] + ]; + + $fieldResolver = $this->readFieldResolver($fieldMeta); + if ($fieldResolver) { + $result['resolver'] = $fieldResolver; + } + + $result = array_merge( + $result, + $this->typeMetaReader->readTypeMeta($fieldTypeMeta, 'OutputField') + ); + + $arguments = $fieldMeta->args; + foreach ($arguments as $argumentMeta) { + $argumentName = $argumentMeta->name; + $result['arguments'][$argumentName] = [ + 'name' => $argumentName, + ]; + $typeMeta = $argumentMeta->getType(); + $result['arguments'][$argumentName] = array_merge( + $result['arguments'][$argumentName], + $this->typeMetaReader->readTypeMeta($typeMeta, 'Argument') + ); + } + return $result; + } + + /** + * @param \GraphQL\Type\Definition\FieldDefinition $fieldMeta + * @return string|null + */ + private function readFieldResolver(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) : ?string + { + /** @var \GraphQL\Language\AST\NodeList $directives */ + $directives = $fieldMeta->astNode->directives; + foreach ($directives as $directive) { + if ($directive->name->value == 'resolver') { + foreach ($directive->arguments as $directiveArgument) { + if ($directiveArgument->name->value == 'class') { + return $directiveArgument->value->value; + } + } + } + } + return null; + } +} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php new file mode 100644 index 0000000000000..891ebb81db722 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader; + +class TypeMetaReader +{ + /** + * Read meta from type meta and parameter type + * + * @param $meta + * @param string $parameterType Argument|OutputField|InputField + * @return array + */ + public function readTypeMeta($meta, $parameterType = 'Argument') : array + { + $result = []; + if ($meta instanceof \GraphQL\Type\Definition\NonNull) { + $result['required'] = true; + $meta = $meta->getWrappedType(); + } else { + $result['required'] = false; + } + if ($meta instanceof \GraphQL\Type\Definition\ListOfType) { + $itemTypeMeta = $meta->ofType; + if ($itemTypeMeta instanceof \GraphQL\Type\Definition\NonNull) { + $result['itemsRequired'] = true; + $itemTypeMeta = $itemTypeMeta->getWrappedType(); + } else { + $result['itemsRequired'] = false; + } + $result['description'] = $itemTypeMeta->description; + $itemTypeName = $itemTypeMeta->name; + $result['itemType'] = $itemTypeName; + if ($this->isScalarType((string)$itemTypeMeta)) { + $result['type'] = 'ScalarArray' . $parameterType; + } else { + $result['type'] = 'ObjectArray' . $parameterType; + } + } else { + $result['description'] = $meta->description; + $result['type'] = $meta->name; + } + return $result; + } + + /** + * Test if type is a scalar type + * + * @param string $type + * @return bool + */ + private function isScalarType(string $type) : bool + { + return in_array($type, ['String', 'Int', 'Float', 'Boolean', 'ID']); + } +} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php new file mode 100644 index 0000000000000..1e90939df5cf8 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Framework\GraphQl\Config\GraphQlReader\Reader; + +use Magento\Framework\GraphQl\Config\GraphQlReader\TypeMetaReaderInterface; + +class EnumType implements TypeMetaReaderInterface +{ + /** + * {@inheritdoc} + */ + public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array + { + if ($typeMeta instanceof \GraphQL\Type\Definition\EnumType) { + $result = [ + 'name' => $typeMeta->name, + 'type' => 'graphql_enum', + 'items' => [] // Populated later + ]; + foreach ($typeMeta->getValues() as $value) { + // TODO: Simplify structure, currently name is lost during conversion to GraphQL schema + $result['items'][$value->value] = [ + 'name' => strtolower($value->name), + '_value' => $value->value + ]; + } + + return $result; + } else { + return null; + } + } +} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php new file mode 100644 index 0000000000000..45669d6f37314 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php @@ -0,0 +1,68 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Framework\GraphQl\Config\GraphQlReader\Reader; + +use Magento\Framework\GraphQl\Config\GraphQlReader\TypeMetaReaderInterface; +use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\TypeMetaReader; + +class InputObjectType implements TypeMetaReaderInterface +{ + /** + * @var TypeMetaReader + */ + private $typeMetaReader; + + /** + * @param TypeMetaReader $typeMetaReader + */ + public function __construct(TypeMetaReader $typeMetaReader) + { + $this->typeMetaReader = $typeMetaReader; + } + + /** + * {@inheritdoc} + */ + public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array + { + if ($typeMeta instanceof \GraphQL\Type\Definition\InputObjectType) { + $typeName = $typeMeta->name; + $result = [ + 'name' => $typeName, + 'type' => 'graphql_input', + 'fields' => [] // Populated later + ]; + $fields = $typeMeta->getFields(); + foreach ($fields as $fieldName => $fieldMeta) { + $result['fields'][$fieldName] = $this->readInputObjectFieldMeta($fieldMeta); + } + return $result; + } else { + return null; + } + } + + /** + * @param \GraphQL\Type\Definition\InputObjectField $fieldMeta + * @return array + */ + private function readInputObjectFieldMeta(\GraphQL\Type\Definition\InputObjectField $fieldMeta) : array + { + $fieldName = $fieldMeta->name; + $typeMeta = $fieldMeta->getType(); + $result = [ + 'name' => $fieldName, + 'required' => false, + // TODO arguments don't make sense here, but expected to be always present in \Magento\Framework\GraphQl\Config\Data\Mapper\TypeMapper::map + 'arguments' => [] + ]; + + $result = array_merge($result, $this->typeMetaReader->readTypeMeta($typeMeta, 'InputField')); + return $result; + } +} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php new file mode 100644 index 0000000000000..39c696c857f2f --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Framework\GraphQl\Config\GraphQlReader\Reader; + +use Magento\Framework\GraphQl\Config\GraphQlReader\TypeMetaReaderInterface; +use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\FieldMetaReader; + +class InterfaceType implements TypeMetaReaderInterface +{ + /** + * @var FieldMetaReader + */ + private $fieldMetaReader; + + /** + * @param FieldMetaReader $fieldMetaReader + */ + public function __construct(FieldMetaReader $fieldMetaReader) + { + $this->fieldMetaReader = $fieldMetaReader; + } + + /** + * @param \GraphQL\Type\Definition\Type $typeMeta + * @return array + */ + public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array + { + if ($typeMeta instanceof \GraphQL\Type\Definition\InterfaceType) { + $typeName = $typeMeta->name; + $result = [ + 'name' => $typeName, + 'type' => 'graphql_interface', + 'fields' => [] + ]; + + $interfaceTypeResolver = $this->getInterfaceTypeResolver($typeMeta); + if ($interfaceTypeResolver) { + $result['typeResolver'] = $interfaceTypeResolver; + } + + $fields = $typeMeta->getFields(); + foreach ($fields as $fieldName => $fieldMeta) { + $result['fields'][$fieldName] = $this->fieldMetaReader->readFieldMeta($fieldMeta); + } + return $result; + } else { + return null; + } + } + + /** + * Retrieve the interface type resolver if it exists from the meta data + * + * @param \GraphQL\Type\Definition\InterfaceType $interfaceTypeMeta + * @return string|null + */ + private function getInterfaceTypeResolver(\GraphQL\Type\Definition\InterfaceType $interfaceTypeMeta) : ?string + { + /** @var \GraphQL\Language\AST\NodeList $directives */ + $directives = $interfaceTypeMeta->astNode->directives; + foreach ($directives as $directive) { + if ($directive->name->value == 'typeResolver') { + foreach ($directive->arguments as $directiveArgument) { + if ($directiveArgument->name->value == 'class') { + return $directiveArgument->value->value; + } + } + } + } + return null; + } +} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php new file mode 100644 index 0000000000000..35bc7fd2e4c14 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Framework\GraphQl\Config\GraphQlReader\Reader; + +use Magento\Framework\GraphQl\Config\GraphQlReader\TypeMetaReaderInterface; +use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\FieldMetaReader; + +class ObjectType implements TypeMetaReaderInterface +{ + /** + * @var FieldMetaReader + */ + private $fieldMetaReader; + + /** + * @param FieldMetaReader $fieldMetaReader + */ + public function __construct(FieldMetaReader $fieldMetaReader) + { + $this->fieldMetaReader = $fieldMetaReader; + } + + /** + * {@inheritdoc} + */ + public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array + { + if ($typeMeta instanceof \GraphQL\Type\Definition\ObjectType) { + $typeName = $typeMeta->name; + $result = [ + 'name' => $typeName, + 'type' => 'graphql_type', + 'fields' => [], // Populated later + + ]; + + $interfaces = $typeMeta->getInterfaces(); + foreach ($interfaces as $interfaceMeta) { + $interfaceName = $interfaceMeta->name; + $result['implements'][$interfaceName] = [ + 'interface' => $interfaceName, + 'copyFields' => true // TODO: Configure in separate config + ]; + } + + $fields = $typeMeta->getFields(); + foreach ($fields as $fieldName => $fieldMeta) { + $result['fields'][$fieldName] = $this->fieldMetaReader->readFieldMeta($fieldMeta); + } + + return $result; + } else { + return null; + } + } +} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/TypeMetaReaderInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/TypeMetaReaderInterface.php new file mode 100644 index 0000000000000..d63901e27ce02 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/TypeMetaReaderInterface.php @@ -0,0 +1,19 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Framework\GraphQl\Config\GraphQlReader; + +interface TypeMetaReaderInterface +{ + /** + * Read schema data from type metadata + * + * @param \GraphQL\Type\Definition\Type $typeMeta + * @return array + */ + public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array; +} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/TypeReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/TypeReader.php new file mode 100644 index 0000000000000..648ad9634dd88 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/TypeReader.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Framework\GraphQl\Config\GraphQlReader; + +class TypeReader implements TypeMetaReaderInterface +{ + /** @var TypeMetaReaderInterface[] */ + private $typeReaders = []; + + /** + * @param array $typeReaders + */ + public function __construct( + $typeReaders = [] + ) { + $this->typeReaders = $typeReaders; + } + + /** + * {@inheritdoc} + */ + public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array + { + foreach ($this->typeReaders as $typeReader) { + $result = $typeReader->read($typeMeta); + if ($result !== null) { + return $result; + } + } + return null; + } +} From 03bbca68e9b6822f06a34bb1d60b9785b0e45b56 Mon Sep 17 00:00:00 2001 From: Sergey <simpleadm@gmail.com> Date: Sun, 18 Mar 2018 21:49:32 +0300 Subject: [PATCH 097/668] Added json and xml support to the post method in socket client --- lib/internal/Magento/Framework/HTTP/Client/Socket.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/HTTP/Client/Socket.php b/lib/internal/Magento/Framework/HTTP/Client/Socket.php index 8157081139788..d229baa5dd476 100644 --- a/lib/internal/Magento/Framework/HTTP/Client/Socket.php +++ b/lib/internal/Magento/Framework/HTTP/Client/Socket.php @@ -273,7 +273,7 @@ protected function parseUrl($uri) * Make POST request * * @param string $uri - * @param array $params + * @param array|string $params use string in case of JSON or XML POST request * @return void */ public function post($uri, $params) @@ -455,10 +455,12 @@ public function getStatus() /** * Make request + * * @param string $method * @param string $uri - * @param array $params + * @param array|string $params use string in case of JSON or XML POST request * @return void + * @throws \Exception */ protected function makeRequest($method, $uri, $params = []) { @@ -473,8 +475,8 @@ protected function makeRequest($method, $uri, $params = []) $appendHeaders = []; $paramsStr = false; - if ($isPost && count($params)) { - $paramsStr = http_build_query($params); + if ($isPost && $params) { + $paramsStr = is_array($params) ? http_build_query($params) : $params; $appendHeaders['Content-type'] = 'application/x-www-form-urlencoded'; $appendHeaders['Content-length'] = strlen($paramsStr); } From b88910a0ec22569f49aad3479a47d97f2304641e Mon Sep 17 00:00:00 2001 From: John Stennett <john00ivy@gmail.com> Date: Mon, 19 Mar 2018 10:45:43 -0500 Subject: [PATCH 098/668] MQE-727: MSI Test Cases - Renaming the "AdminSaveAndClose" action group to "AdminFormSaveAndClose". --- .../Ui/ActionGroup/AdminSaveAndCloseActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminSaveAndCloseActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminSaveAndCloseActionGroup.xml index dc53ed1df9860..b8c36ba0b485f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminSaveAndCloseActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/ActionGroup/AdminSaveAndCloseActionGroup.xml @@ -8,7 +8,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminSaveAndClose"> + <actionGroup name="AdminFormSaveAndClose"> <click selector="{{AdminProductFormActionSection.saveArrow}}" stepKey="openSaveDropDown"/> <click selector="{{AdminProductFormActionSection.saveAndClose}}" stepKey="clickOnSaveAndClose"/> <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertSaveMessageSuccess"/> From 06f27889581811865102e0adda0310d9213c5c97 Mon Sep 17 00:00:00 2001 From: Ben Batschelet <bbatschelet@magento.com> Date: Mon, 19 Mar 2018 11:13:36 -0500 Subject: [PATCH 099/668] Add countable interface to classes with count() method --- lib/internal/Magento/Framework/DB/Tree/NodeSet.php | 2 +- lib/internal/Magento/Framework/Data/Form/Element/Collection.php | 2 +- lib/internal/Magento/Framework/Data/Tree/Node/Collection.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/DB/Tree/NodeSet.php b/lib/internal/Magento/Framework/DB/Tree/NodeSet.php index 52d67398303bd..46a2497a8343f 100644 --- a/lib/internal/Magento/Framework/DB/Tree/NodeSet.php +++ b/lib/internal/Magento/Framework/DB/Tree/NodeSet.php @@ -9,7 +9,7 @@ * TODO implements iterators * */ -class NodeSet implements \Iterator +class NodeSet implements \Iterator, \Countable { /** * @var Node[] diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Collection.php b/lib/internal/Magento/Framework/Data/Form/Element/Collection.php index 7a544501861bd..ced1f4208223d 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Collection.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Collection.php @@ -13,7 +13,7 @@ * * @author Magento Core Team <core@magentocommerce.com> */ -class Collection implements \ArrayAccess, \IteratorAggregate +class Collection implements \ArrayAccess, \IteratorAggregate, \Countable { /** * Elements storage diff --git a/lib/internal/Magento/Framework/Data/Tree/Node/Collection.php b/lib/internal/Magento/Framework/Data/Tree/Node/Collection.php index 832fd18b48606..94990c0340a83 100644 --- a/lib/internal/Magento/Framework/Data/Tree/Node/Collection.php +++ b/lib/internal/Magento/Framework/Data/Tree/Node/Collection.php @@ -17,7 +17,7 @@ /** * @api */ -class Collection implements \ArrayAccess, \IteratorAggregate +class Collection implements \ArrayAccess, \IteratorAggregate, \Countable { /** * @var array From ced6573b611382675cc30323a5ba04fbf1add0d0 Mon Sep 17 00:00:00 2001 From: Ben Batschelet <bbatschelet@magento.com> Date: Mon, 19 Mar 2018 11:14:16 -0500 Subject: [PATCH 100/668] Method getColumns() may return null --- .../Magento/Backend/view/adminhtml/templates/widget/grid.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml index c99759a60d1bf..c665c1095a549 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml @@ -19,7 +19,7 @@ * */ /* @var $block \Magento\Backend\Block\Widget\Grid */ -$numColumns = sizeof($block->getColumns()); +$numColumns = !is_null($block->getColumns()) ? sizeof($block->getColumns()) : 0; ?> <?php if ($block->getCollection()): ?> From ea56254a27da64c9ad10bf109f2a314c40dabbc4 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Mon, 19 Mar 2018 14:08:21 -0500 Subject: [PATCH 101/668] MAGETWO-89350: php version in composer.json of some components is inconsistent with php version in root composer.json --- app/code/Magento/AdvancedSearch/composer.json | 2 +- app/code/Magento/Amqp/composer.json | 2 +- app/code/Magento/AsynchronousOperations/composer.json | 2 +- app/code/Magento/Elasticsearch/composer.json | 2 +- app/code/Magento/MessageQueue/composer.json | 2 +- app/code/Magento/MysqlMq/composer.json | 2 +- app/design/adminhtml/Magento/backend/composer.json | 2 +- app/design/frontend/Magento/blank/composer.json | 2 +- app/design/frontend/Magento/luma/composer.json | 2 +- app/design/frontend/Magento/rush/composer.json | 2 +- .../Magento/FunctionalTest/AdminNotification/composer.json | 2 +- .../FunctionalTest/AdvancedPricingImportExport/composer.json | 2 +- .../Magento/FunctionalTest/AdvancedSearch/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Amqp/composer.json | 2 +- .../functional/Magento/FunctionalTest/Analytics/composer.json | 2 +- .../Magento/FunctionalTest/AsynchronousOperations/composer.json | 2 +- .../Magento/FunctionalTest/Authorization/composer.json | 2 +- .../Magento/FunctionalTest/Authorizenet/composer.json | 2 +- .../functional/Magento/FunctionalTest/Backend/composer.json | 2 +- .../functional/Magento/FunctionalTest/Backup/composer.json | 2 +- .../functional/Magento/FunctionalTest/Braintree/composer.json | 2 +- .../functional/Magento/FunctionalTest/Bundle/composer.json | 2 +- .../Magento/FunctionalTest/BundleImportExport/composer.json | 2 +- .../Magento/FunctionalTest/CacheInvalidate/composer.json | 2 +- .../functional/Magento/FunctionalTest/Captcha/composer.json | 2 +- .../functional/Magento/FunctionalTest/Catalog/composer.json | 2 +- .../Magento/FunctionalTest/CatalogAnalytics/composer.json | 2 +- .../Magento/FunctionalTest/CatalogImportExport/composer.json | 2 +- .../Magento/FunctionalTest/CatalogInventory/composer.json | 2 +- .../functional/Magento/FunctionalTest/CatalogRule/composer.json | 2 +- .../FunctionalTest/CatalogRuleConfigurable/composer.json | 2 +- .../Magento/FunctionalTest/CatalogSearch/composer.json | 2 +- .../Magento/FunctionalTest/CatalogUrlRewrite/composer.json | 2 +- .../Magento/FunctionalTest/CatalogWidget/composer.json | 2 +- .../functional/Magento/FunctionalTest/Checkout/composer.json | 2 +- .../Magento/FunctionalTest/CheckoutAgreements/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Cms/composer.json | 2 +- .../Magento/FunctionalTest/CmsUrlRewrite/composer.json | 2 +- .../functional/Magento/FunctionalTest/Config/composer.json | 2 +- .../FunctionalTest/ConfigurableImportExport/composer.json | 2 +- .../Magento/FunctionalTest/ConfigurableProduct/composer.json | 2 +- .../ConfigurableProductCatalogSearch/composer.json | 2 +- .../FunctionalTest/ConfigurableProductSales/composer.json | 2 +- .../FunctionalTest/ConfigurableProductWishlist/composer.json | 2 +- .../functional/Magento/FunctionalTest/Contact/composer.json | 2 +- .../functional/Magento/FunctionalTest/Cookie/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Cron/composer.json | 2 +- .../Magento/FunctionalTest/CurrencySymbol/composer.json | 2 +- .../functional/Magento/FunctionalTest/Customer/composer.json | 2 +- .../Magento/FunctionalTest/CustomerAnalytics/composer.json | 2 +- .../Magento/FunctionalTest/CustomerImportExport/composer.json | 2 +- .../functional/Magento/FunctionalTest/Deploy/composer.json | 2 +- .../functional/Magento/FunctionalTest/Developer/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Dhl/composer.json | 2 +- .../functional/Magento/FunctionalTest/Directory/composer.json | 2 +- .../Magento/FunctionalTest/Downloadable/composer.json | 2 +- .../FunctionalTest/DownloadableImportExport/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Eav/composer.json | 2 +- .../Magento/FunctionalTest/Elasticsearch/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Email/composer.json | 2 +- .../Magento/FunctionalTest/EncryptionKey/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Fedex/composer.json | 2 +- .../functional/Magento/FunctionalTest/Framework/composer.json | 2 +- .../functional/Magento/FunctionalTest/GiftMessage/composer.json | 2 +- .../Magento/FunctionalTest/GoogleAdwords/composer.json | 2 +- .../Magento/FunctionalTest/GoogleAnalytics/composer.json | 2 +- .../Magento/FunctionalTest/GoogleOptimizer/composer.json | 2 +- .../functional/Magento/FunctionalTest/GraphQl/composer.json | 2 +- .../Magento/FunctionalTest/GroupedImportExport/composer.json | 2 +- .../Magento/FunctionalTest/GroupedProduct/composer.json | 2 +- .../Magento/FunctionalTest/ImportExport/composer.json | 2 +- .../functional/Magento/FunctionalTest/Indexer/composer.json | 2 +- .../Magento/FunctionalTest/InstantPurchase/composer.json | 2 +- .../functional/Magento/FunctionalTest/Integration/composer.json | 2 +- .../Magento/FunctionalTest/LayeredNavigation/composer.json | 2 +- .../functional/Magento/FunctionalTest/Marketplace/composer.json | 2 +- .../Magento/FunctionalTest/MediaStorage/composer.json | 2 +- .../Magento/FunctionalTest/MessageQueue/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Msrp/composer.json | 2 +- .../Magento/FunctionalTest/Multishipping/composer.json | 2 +- .../functional/Magento/FunctionalTest/MysqlMq/composer.json | 2 +- .../Magento/FunctionalTest/NewRelicReporting/composer.json | 2 +- .../functional/Magento/FunctionalTest/Newsletter/composer.json | 2 +- .../Magento/FunctionalTest/OfflinePayments/composer.json | 2 +- .../Magento/FunctionalTest/OfflineShipping/composer.json | 2 +- .../functional/Magento/FunctionalTest/PageCache/composer.json | 2 +- .../functional/Magento/FunctionalTest/Payment/composer.json | 2 +- .../functional/Magento/FunctionalTest/Paypal/composer.json | 2 +- .../functional/Magento/FunctionalTest/Persistent/composer.json | 2 +- .../Magento/FunctionalTest/ProductAlert/composer.json | 2 +- .../Magento/FunctionalTest/ProductVideo/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Quote/composer.json | 2 +- .../Magento/FunctionalTest/QuoteAnalytics/composer.json | 2 +- .../functional/Magento/FunctionalTest/Reports/composer.json | 2 +- .../functional/Magento/FunctionalTest/RequireJs/composer.json | 2 +- .../functional/Magento/FunctionalTest/Review/composer.json | 2 +- .../Magento/FunctionalTest/ReviewAnalytics/composer.json | 2 +- .../functional/Magento/FunctionalTest/Robots/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Rss/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Rule/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Sales/composer.json | 2 +- .../Magento/FunctionalTest/SalesAnalytics/composer.json | 2 +- .../Magento/FunctionalTest/SalesInventory/composer.json | 2 +- .../functional/Magento/FunctionalTest/SalesRule/composer.json | 2 +- .../Magento/FunctionalTest/SalesSequence/composer.json | 2 +- .../functional/Magento/FunctionalTest/SampleData/composer.json | 2 +- .../Magento/FunctionalTest/SampleTemplates/composer.json | 2 +- .../functional/Magento/FunctionalTest/SampleTests/composer.json | 2 +- .../functional/Magento/FunctionalTest/Search/composer.json | 2 +- .../functional/Magento/FunctionalTest/Security/composer.json | 2 +- .../functional/Magento/FunctionalTest/SendFriend/composer.json | 2 +- .../functional/Magento/FunctionalTest/Shipping/composer.json | 2 +- .../functional/Magento/FunctionalTest/Sitemap/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Store/composer.json | 2 +- .../functional/Magento/FunctionalTest/Swagger/composer.json | 2 +- .../functional/Magento/FunctionalTest/Swatches/composer.json | 2 +- .../FunctionalTest/SwatchesLayeredNavigation/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Tax/composer.json | 2 +- .../Magento/FunctionalTest/TaxImportExport/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Theme/composer.json | 2 +- .../functional/Magento/FunctionalTest/Translation/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Ui/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Ups/composer.json | 2 +- .../functional/Magento/FunctionalTest/UrlRewrite/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/User/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Usps/composer.json | 2 +- .../functional/Magento/FunctionalTest/Variable/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Vault/composer.json | 2 +- .../functional/Magento/FunctionalTest/Version/composer.json | 2 +- .../functional/Magento/FunctionalTest/Webapi/composer.json | 2 +- .../Magento/FunctionalTest/WebapiSecurity/composer.json | 2 +- .../tests/functional/Magento/FunctionalTest/Weee/composer.json | 2 +- .../functional/Magento/FunctionalTest/Widget/composer.json | 2 +- .../functional/Magento/FunctionalTest/Wishlist/composer.json | 2 +- .../Magento/FunctionalTest/WishlistAnalytics/composer.json | 2 +- .../Magento/TestModuleMessageQueueConfigOverride/composer.json | 2 +- .../Magento/TestModuleMessageQueueConfiguration/composer.json | 2 +- lib/internal/Magento/Framework/Amqp/composer.json | 2 +- lib/internal/Magento/Framework/Bulk/composer.json | 2 +- lib/internal/Magento/Framework/MessageQueue/composer.json | 2 +- 140 files changed, 140 insertions(+), 140 deletions(-) diff --git a/app/code/Magento/AdvancedSearch/composer.json b/app/code/Magento/AdvancedSearch/composer.json index 2d549c12235db..83032dd8bdea6 100644 --- a/app/code/Magento/AdvancedSearch/composer.json +++ b/app/code/Magento/AdvancedSearch/composer.json @@ -13,7 +13,7 @@ "magento/module-customer": "100.3.*", "magento/module-search": "100.3.*", "magento/module-store": "100.3.*", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "type": "magento2-module", "version": "100.3.0-dev", diff --git a/app/code/Magento/Amqp/composer.json b/app/code/Magento/Amqp/composer.json index 255fa5d55d935..cb056d6488ace 100644 --- a/app/code/Magento/Amqp/composer.json +++ b/app/code/Magento/Amqp/composer.json @@ -8,7 +8,7 @@ "magento/framework": "100.3.*", "magento/framework-amqp": "100.1.*", "magento/framework-message-queue": "100.3.*", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "type": "magento2-module", "version": "100.3.0-dev", diff --git a/app/code/Magento/AsynchronousOperations/composer.json b/app/code/Magento/AsynchronousOperations/composer.json index 7a4e7f6aad69c..19f1ce2fc8125 100644 --- a/app/code/Magento/AsynchronousOperations/composer.json +++ b/app/code/Magento/AsynchronousOperations/composer.json @@ -11,7 +11,7 @@ "magento/module-backend": "100.3.*", "magento/module-ui": "100.3.*", "magento/module-user": "100.3.*", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/module-admin-notification": "100.3.*", diff --git a/app/code/Magento/Elasticsearch/composer.json b/app/code/Magento/Elasticsearch/composer.json index 00a0021c5a100..eaba6fe83a759 100644 --- a/app/code/Magento/Elasticsearch/composer.json +++ b/app/code/Magento/Elasticsearch/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-elasticsearch", "description": "N/A", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/module-advanced-search": "100.2.*", "magento/module-catalog": "102.0.*", "magento/module-catalog-search": "100.2.*", diff --git a/app/code/Magento/MessageQueue/composer.json b/app/code/Magento/MessageQueue/composer.json index d96c82a9636a2..870cc28dbcaee 100644 --- a/app/code/Magento/MessageQueue/composer.json +++ b/app/code/Magento/MessageQueue/composer.json @@ -7,7 +7,7 @@ "require": { "magento/framework": "100.3.*", "magento/magento-composer-installer": "*", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "type": "magento2-module", "version": "100.3.0-dev", diff --git a/app/code/Magento/MysqlMq/composer.json b/app/code/Magento/MysqlMq/composer.json index 8945fa2a6144b..f4e6c64978bdf 100644 --- a/app/code/Magento/MysqlMq/composer.json +++ b/app/code/Magento/MysqlMq/composer.json @@ -8,7 +8,7 @@ "magento/framework": "100.3.*", "magento/magento-composer-installer": "*", "magento/module-store": "100.3.*", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "type": "magento2-module", "version": "100.3.0-dev", diff --git a/app/design/adminhtml/Magento/backend/composer.json b/app/design/adminhtml/Magento/backend/composer.json index a7497d174c421..a0142d7e510e2 100644 --- a/app/design/adminhtml/Magento/backend/composer.json +++ b/app/design/adminhtml/Magento/backend/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*" }, "type": "magento2-theme", diff --git a/app/design/frontend/Magento/blank/composer.json b/app/design/frontend/Magento/blank/composer.json index 5b58622e2e286..e7110510dcd61 100644 --- a/app/design/frontend/Magento/blank/composer.json +++ b/app/design/frontend/Magento/blank/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*" }, "type": "magento2-theme", diff --git a/app/design/frontend/Magento/luma/composer.json b/app/design/frontend/Magento/luma/composer.json index 33f4c4e8a91b7..42e49155790d3 100644 --- a/app/design/frontend/Magento/luma/composer.json +++ b/app/design/frontend/Magento/luma/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*", "magento/theme-frontend-blank": "100.3.*" }, diff --git a/app/design/frontend/Magento/rush/composer.json b/app/design/frontend/Magento/rush/composer.json index 15d3c30662f68..133e18cafa3f6 100644 --- a/app/design/frontend/Magento/rush/composer.json +++ b/app/design/frontend/Magento/rush/composer.json @@ -2,7 +2,7 @@ "name": "magento/theme-frontend-rush", "description": "N/A", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.3.*" }, "type": "magento2-theme", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdminNotification/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdminNotification/composer.json index c6ec48b2930e5..49a59426cfa6d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdminNotification/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdminNotification/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedPricingImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedPricingImportExport/composer.json index 4c0832605ae1d..96be03e146356 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedPricingImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedPricingImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedSearch/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedSearch/composer.json index 730653d9bbc86..cd266da628c37 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedSearch/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AdvancedSearch/composer.json @@ -11,7 +11,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Amqp/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Amqp/composer.json index 87071431219cb..82c2915dce58b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Amqp/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Amqp/composer.json @@ -11,7 +11,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/composer.json index 9245dc6e40766..cb59843c9cba8 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AsynchronousOperations/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AsynchronousOperations/composer.json index 5f13cad7fbb52..240b8aa3cca35 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AsynchronousOperations/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/AsynchronousOperations/composer.json @@ -11,7 +11,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorization/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorization/composer.json index 4e78766d9d135..2eab99a968a9a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorization/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorization/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorizenet/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorizenet/composer.json index 80d7737565277..06dce68805cd9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorizenet/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Authorizenet/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/composer.json index 2d2dd01724f81..b2a99b07f0255 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backup": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backup/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backup/composer.json index a77c84d925563..c6e51064c592f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backup/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backup/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Braintree/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Braintree/composer.json index e91cba389bbff..d3a13786a0a9d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Braintree/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Braintree/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/composer.json index d76fd5195c3f3..2219c9aa586bf 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/composer.json @@ -13,7 +13,7 @@ "require": { "magento/magento2-functional-testing-framework": "1.0.0", "magento/magento2-functional-test-module-catalog": "100.0.0-dev", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/BundleImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/BundleImportExport/composer.json index 1653aebe65ded..fd79ec03d4ea9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/BundleImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/BundleImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-bundle": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CacheInvalidate/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CacheInvalidate/composer.json index 3d8072140d268..f59864d2a14ea 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CacheInvalidate/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CacheInvalidate/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-page-cache": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Captcha/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Captcha/composer.json index 6b5beca7862e1..0297dbb343bcb 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Captcha/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Captcha/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/composer.json index a4c32f5a2436e..c8f2484c9025a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/composer.json @@ -18,7 +18,7 @@ "magento/magento2-functional-test-module-quote": "100.0.0-dev", "magento/magento2-functional-test-module-theme": "100.0.0-dev", "magento/magento2-functional-test-module-ui": "100.0.0-dev", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog-inventory": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogAnalytics/composer.json index b742218731f84..cce1015d0d2e5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogImportExport/composer.json index 22866e9abd2c1..b2b0b3965429a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogInventory/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogInventory/composer.json index ba124db346ae5..432acba351bc3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogInventory/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogInventory/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/composer.json index b478cb58583b5..49b2aeb653fb1 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRuleConfigurable/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRuleConfigurable/composer.json index b232f1e8563b0..62be67eaed6da 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRuleConfigurable/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRuleConfigurable/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/composer.json index 132dbba8f8365..a31c7e6dc526c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/composer.json @@ -16,7 +16,7 @@ "magento/magento2-functional-test-module-search": "100.0.0-dev", "magento/magento2-functional-test-module-theme": "100.0.0-dev", "magento/magento2-functional-test-module-ui": "100.0.0-dev", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogUrlRewrite/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogUrlRewrite/composer.json index 771e0385eccbc..a6b42de511466 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogUrlRewrite/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogUrlRewrite/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogWidget/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogWidget/composer.json index 1427c1af64b02..5550db57606ba 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogWidget/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogWidget/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/composer.json index cec9325d2eb60..130cd79c8d5ef 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/composer.json @@ -21,7 +21,7 @@ "magento/magento2-functional-test-module-shipping": "100.0.0-dev", "magento/magento2-functional-test-module-theme": "100.0.0-dev", "magento/magento2-functional-test-module-ui": "100.0.0-dev", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CheckoutAgreements/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CheckoutAgreements/composer.json index 8860639e22883..fe061803b297b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CheckoutAgreements/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CheckoutAgreements/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/composer.json index c1d868e742226..07aa529e45e14 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CmsUrlRewrite/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CmsUrlRewrite/composer.json index c4ad8b0dc2f71..7c35ddafd671d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CmsUrlRewrite/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CmsUrlRewrite/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-cms": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/composer.json index b556ce773a6d3..4f3c721c582b1 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableImportExport/composer.json index b512f02910419..2d8699d4999d5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/composer.json index 60dc9a490fd85..e9f74ef5ddbc6 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/composer.json @@ -16,7 +16,7 @@ "magento/magento2-functional-test-module-checkout": "100.0.0-dev", "magento/magento2-functional-test-module-quote": "100.0.0-dev", "magento/magento2-functional-test-module-ui": "100.0.0-dev", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductCatalogSearch/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductCatalogSearch/composer.json index cbe5f173a3827..df8598a93a2d8 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductCatalogSearch/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductCatalogSearch/composer.json @@ -15,7 +15,7 @@ "magento/magento2-functional-test-module-catalog": "100.0.0-dev", "magento/magento2-functional-test-module-catalog-search": "100.0.0-dev", "magento/magento2-functional-test-module-configurable-product": "100.0.0-dev", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductSales/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductSales/composer.json index 36389d2cc51bb..629ead23ae981 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductSales/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductSales/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductWishlist/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductWishlist/composer.json index 5da136f954255..e7f61c1bc660d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductWishlist/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductWishlist/composer.json @@ -15,7 +15,7 @@ "magento/magento2-functional-test-module-catalog": "100.0.0-dev", "magento/magento2-functional-test-module-configurable-product": "100.0.0-dev", "magento/magento2-functional-test-module-wishlist": "100.0.0-dev", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Contact/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Contact/composer.json index 928012f706a4a..b77a865b04de1 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Contact/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Contact/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-cms": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cookie/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cookie/composer.json index 9aff0ad424117..4d55d54479092 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cookie/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cookie/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-store": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cron/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cron/composer.json index a4136569d26fc..ad913508c5cbb 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cron/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cron/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-store": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CurrencySymbol/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CurrencySymbol/composer.json index f11a1371b395a..335cee4939672 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CurrencySymbol/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CurrencySymbol/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/composer.json index e75cac61cb228..e6e178fbcd163 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerAnalytics/composer.json index 84a73e12eb4ff..6082e25ee87ac 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-customer": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerImportExport/composer.json index a63a0cc71af20..09caca0289949 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CustomerImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Deploy/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Deploy/composer.json index 49a9b5333133e..6cc25c9975ac9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Deploy/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Deploy/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-config": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Developer/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Developer/composer.json index ec19ec7de8e37..d20bf30c17289 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Developer/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Developer/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-config": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Dhl/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Dhl/composer.json index 6ce6995f55137..9d2da35038bfe 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Dhl/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Dhl/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Directory/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Directory/composer.json index 30a6dccdd6876..8262f404e93a3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Directory/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Directory/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/composer.json index cb97370b3d73f..16f9f02ac24a4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/composer.json @@ -13,7 +13,7 @@ "require": { "magento/magento2-functional-testing-framework": "1.0.0", "magento/magento2-functional-test-module-catalog": "100.0.0-dev", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/DownloadableImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/DownloadableImportExport/composer.json index 5078e028732b4..2c3b8fd9ce566 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/DownloadableImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/DownloadableImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Eav/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Eav/composer.json index e14cf4a78bc3f..06db9b63d7387 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Eav/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Eav/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Elasticsearch/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Elasticsearch/composer.json index 26dcd83a4dda4..c6f85999d3dea 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Elasticsearch/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Elasticsearch/composer.json @@ -11,7 +11,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-advanced-search": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Email/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Email/composer.json index 6627c6b77fd0d..e95fc4ca907e3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Email/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Email/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/EncryptionKey/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/EncryptionKey/composer.json index 371c1f30b8dab..0252e03b31808 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/EncryptionKey/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/EncryptionKey/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Fedex/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Fedex/composer.json index 1cf32f0772260..5cf3ea9132e2a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Fedex/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Fedex/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/composer.json index e5a2f7fbe9e0f..3a00a525a5478 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "~2.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GiftMessage/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GiftMessage/composer.json index a00f20427c706..5cc515e5922d9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GiftMessage/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GiftMessage/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAdwords/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAdwords/composer.json index cd3804122ec1f..8710e25cd469d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAdwords/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAdwords/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-sales": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAnalytics/composer.json index 3ac4ba7a20c08..63b7597a9d391 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-cookie": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleOptimizer/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleOptimizer/composer.json index 7bd4832051827..71d48969544e3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleOptimizer/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GoogleOptimizer/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GraphQl/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GraphQl/composer.json index 05749f8295eba..701ed734f896c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GraphQl/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GraphQl/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-webapi": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedImportExport/composer.json index a5f2f1d4c9b3f..4460aef0ac60f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/composer.json index 1e484a6d48433..ddc23e730436d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/composer.json @@ -13,7 +13,7 @@ "require": { "magento/magento2-functional-testing-framework": "1.0.0", "magento/magento2-functional-test-module-catalog": "100.0.0-dev", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ImportExport/composer.json index c575fa78375de..4632adb4f904f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Indexer/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Indexer/composer.json index c8b81673fe810..35b8219186bd2 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Indexer/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Indexer/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/InstantPurchase/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/InstantPurchase/composer.json index b4e471fd62ed6..84c595020968c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/InstantPurchase/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/InstantPurchase/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-store": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Integration/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Integration/composer.json index 3fcda364a88cc..9f0ccb76c1cd3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Integration/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Integration/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/LayeredNavigation/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/LayeredNavigation/composer.json index dc2725e4a1d1e..447f3ba38a06c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/LayeredNavigation/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/LayeredNavigation/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Marketplace/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Marketplace/composer.json index 7f0909ff460a6..d4079dfefc9ba 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Marketplace/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Marketplace/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MediaStorage/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MediaStorage/composer.json index ef0cf6d0e7ec5..29657d03014bf 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MediaStorage/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MediaStorage/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MessageQueue/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MessageQueue/composer.json index 6b9d8196a58d8..10ae24c3b5448 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MessageQueue/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MessageQueue/composer.json @@ -11,7 +11,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Msrp/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Msrp/composer.json index 5d1d5b4e3f74a..b91aaddcba3f2 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Msrp/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Msrp/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Multishipping/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Multishipping/composer.json index cbc1fd9519105..ffd80908ed522 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Multishipping/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Multishipping/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MysqlMq/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MysqlMq/composer.json index 0b741f776abdc..a647b1d6249a3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MysqlMq/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/MysqlMq/composer.json @@ -11,7 +11,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-store": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/NewRelicReporting/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/NewRelicReporting/composer.json index 014a5773c9520..c6b60c43b6de0 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/NewRelicReporting/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/NewRelicReporting/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/composer.json index 131cc853f0438..eff14e85b04a0 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflinePayments/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflinePayments/composer.json index f4adf1b4a8603..f645c45abfdd0 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflinePayments/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflinePayments/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflineShipping/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflineShipping/composer.json index fb6bcd89a5c00..2fc319facc683 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflineShipping/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/OfflineShipping/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/composer.json index c932ed0861247..2c4612b71a126 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Payment/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Payment/composer.json index 2f2b7fb8675e1..ea5f918171c8f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Payment/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Payment/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Paypal/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Paypal/composer.json index 9af738c291089..94c3af772673e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Paypal/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Paypal/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/composer.json index ec4f6754e5838..e12542a65d2be 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductAlert/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductAlert/composer.json index 93e3633101a8b..1dc3837e4b1fb 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductAlert/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductAlert/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductVideo/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductVideo/composer.json index c3766646ad050..0e1f83433049a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductVideo/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ProductVideo/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Quote/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Quote/composer.json index 4394d1f6ad3ad..7d3a16063745f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Quote/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Quote/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/QuoteAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/QuoteAnalytics/composer.json index 4bd28d1b3c903..0d249b0c40921 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/QuoteAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/QuoteAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-quote": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Reports/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Reports/composer.json index f76c29252118a..53d7e7b1c9c0e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Reports/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Reports/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/RequireJs/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/RequireJs/composer.json index b184fe40ce33b..2fcf3dc4c6103 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/RequireJs/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/RequireJs/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Review/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Review/composer.json index 10bcc87798b8c..4445be9e856cf 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Review/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Review/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ReviewAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ReviewAnalytics/composer.json index 546a20fe50c0f..d58c62a68dac5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ReviewAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ReviewAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-review": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Robots/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Robots/composer.json index 3b83ca8565b05..70cf4ba3203e4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Robots/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Robots/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-store": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rss/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rss/composer.json index 80ec362c2ce2e..9fa6d370cd610 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rss/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rss/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rule/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rule/composer.json index 30f200468e3f9..73dd74c5fa576 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rule/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Rule/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/composer.json index cd4c0fde66877..c339cb1cea0c1 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/composer.json @@ -17,7 +17,7 @@ "magento/magento2-functional-test-module-ui": "100.0.0-dev", "magento/magento2-functional-test-module-payment": "100.0.0-dev", "magento/magento2-functional-test-module-quote": "100.0.0-dev", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesAnalytics/composer.json index 0b37233aa5927..3f96160f374d0 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-sales": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesInventory/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesInventory/composer.json index c4ab23c2d110e..6547bff428193 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesInventory/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesInventory/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/composer.json index 9b914c5df71b6..990fdc0201930 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/composer.json @@ -15,7 +15,7 @@ "magento/magento2-functional-test-module-catalog": "100.0.0-dev", "magento/magento2-functional-test-module-quote": "100.0.0-dev", "magento/magento2-functional-test-module-ui": "100.0.0-dev", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesSequence/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesSequence/composer.json index fb83f886ec02d..808f1394d6173 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesSequence/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesSequence/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleData/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleData/composer.json index 8b531192d0fe1..ed12f8bda3beb 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleData/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleData/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/composer.json index 81528e77bf827..e0ceb5bd23c1c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/composer.json index 7fdf84d34f99f..dc91e593e745b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Search/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Search/composer.json index fdc828cd35a8a..436bc7d1c4e3f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Search/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Search/composer.json @@ -14,7 +14,7 @@ "magento/magento2-functional-testing-framework": "~2.0.0", "magento/magento2-functional-test-module-catalog-search": "100.0.0-dev", "magento/magento2-functional-test-module-ui": "100.0.0-dev", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Security/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Security/composer.json index 2ecb67d87d8ca..69f18fcfbc40f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Security/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Security/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SendFriend/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SendFriend/composer.json index 5f8bcdf51630f..0b7d03fa71fa7 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SendFriend/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SendFriend/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/composer.json index bbd403aa22894..fbe922ddc2d5c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/composer.json index 4ec67bdb7e675..6d1c9eb72dab4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sitemap/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/composer.json index 506e9cc06fdff..718efc04391ca 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/composer.json index ece658104cfe0..b9460ce939e86 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swagger/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/composer.json index 1afb21a4e87bd..9632be9c9f172 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Swatches/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/composer.json index 330478b6e929d..0931a3c286d0a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SwatchesLayeredNavigation/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json index 8c50d2d39a5f0..fb47e3fbeba58 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/composer.json index aff82b7a84e05..364981ffd1e95 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/TaxImportExport/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Theme/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Theme/composer.json index b70bf72bfa9e5..568b31e090ca2 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Theme/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Theme/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "~2.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/composer.json index c44f92a1dfcb9..3a0fb712810ad 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Translation/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/composer.json index 905890a4cea9a..219f938fed196 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ui/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/composer.json index 06534e3b2b469..11aea7bbc68b7 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Ups/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/composer.json index ab7e60435564d..d88d9a54264ee 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/UrlRewrite/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/composer.json index e4ab9263b5c9c..07c2ed3745de5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Usps/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Usps/composer.json index 4a6d5462d8016..5896bff636205 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Usps/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Usps/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-catalog": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/composer.json index 386ebdeedbf47..d70e75da77a03 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Vault/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Vault/composer.json index 9fa8fc8f6b6ec..88ce9046df10c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Vault/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Vault/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-checkout": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Version/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Version/composer.json index 69078adc39303..8a256bc40d42a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Version/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Version/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Webapi/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Webapi/composer.json index 7ddb760e9eb11..a00dbd244615f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Webapi/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Webapi/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-authorization": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WebapiSecurity/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WebapiSecurity/composer.json index 5ec58e1ff9e0f..3c26635fc3f6e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WebapiSecurity/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WebapiSecurity/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-webapi": "100.0.0-dev" diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Weee/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Weee/composer.json index 019d957e96c54..b226f2b1697fa 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Weee/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Weee/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Widget/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Widget/composer.json index 94a03b6c64eeb..85c1d19bd696c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Widget/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Widget/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/composer.json index 91bdd392c8863..9f1358b3ec8b7 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/composer.json @@ -15,7 +15,7 @@ "magento/magento2-functional-test-module-catalog": "100.0.0-dev", "magento/magento2-functional-test-module-checkout": "100.0.0-dev", "magento/magento2-functional-test-module-customer": "100.0.0-dev", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WishlistAnalytics/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WishlistAnalytics/composer.json index b49a321f44884..1f25efea7f90f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WishlistAnalytics/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/WishlistAnalytics/composer.json @@ -12,7 +12,7 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "suggest": { "magento/magento2-functional-test-module-wishlist": "100.0.0-dev" diff --git a/dev/tests/integration/_files/Magento/TestModuleMessageQueueConfigOverride/composer.json b/dev/tests/integration/_files/Magento/TestModuleMessageQueueConfigOverride/composer.json index dd4cc64824881..3f5df3a45943d 100644 --- a/dev/tests/integration/_files/Magento/TestModuleMessageQueueConfigOverride/composer.json +++ b/dev/tests/integration/_files/Magento/TestModuleMessageQueueConfigOverride/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-test-module-message-queue-config-override", "description": "test module for message queue configuration", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.1.*", "magento/module-integration": "100.1.*" }, diff --git a/dev/tests/integration/_files/Magento/TestModuleMessageQueueConfiguration/composer.json b/dev/tests/integration/_files/Magento/TestModuleMessageQueueConfiguration/composer.json index 9cc4af3df9fe9..c8427e5ab5b8a 100644 --- a/dev/tests/integration/_files/Magento/TestModuleMessageQueueConfiguration/composer.json +++ b/dev/tests/integration/_files/Magento/TestModuleMessageQueueConfiguration/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-test-module-message-queue-configuration", "description": "test module for message queue configuration", "require": { - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "magento/framework": "100.1.*", "magento/module-integration": "100.1.*" }, diff --git a/lib/internal/Magento/Framework/Amqp/composer.json b/lib/internal/Magento/Framework/Amqp/composer.json index 7bcd2fe1b8b26..2fa84f7ed3e5d 100644 --- a/lib/internal/Magento/Framework/Amqp/composer.json +++ b/lib/internal/Magento/Framework/Amqp/composer.json @@ -12,7 +12,7 @@ ], "require": { "magento/framework": "100.3.*", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "php": "~7.1.3||~7.2.0", "php-amqplib/php-amqplib": "2.5.*" }, "autoload": { diff --git a/lib/internal/Magento/Framework/Bulk/composer.json b/lib/internal/Magento/Framework/Bulk/composer.json index 8cb9139ca0d52..6e138f0a4f16e 100644 --- a/lib/internal/Magento/Framework/Bulk/composer.json +++ b/lib/internal/Magento/Framework/Bulk/composer.json @@ -12,7 +12,7 @@ ], "require": { "magento/framework": "100.3.*", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { diff --git a/lib/internal/Magento/Framework/MessageQueue/composer.json b/lib/internal/Magento/Framework/MessageQueue/composer.json index 05f119630a4fe..c51d9dace5b0f 100644 --- a/lib/internal/Magento/Framework/MessageQueue/composer.json +++ b/lib/internal/Magento/Framework/MessageQueue/composer.json @@ -12,7 +12,7 @@ ], "require": { "magento/framework": "100.3.*", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + "php": "~7.1.3||~7.2.0" }, "autoload": { "psr-4": { From ef54888435b78134def3c5df960da2daec56ec7f Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Mon, 19 Mar 2018 14:47:41 -0500 Subject: [PATCH 102/668] MAGETWO-89350: php version in composer.json of some components is inconsistent with php version in root composer.json - fix mftf and mtf composer.json files --- dev/tests/acceptance/composer.json | 2 +- dev/tests/functional/composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/acceptance/composer.json b/dev/tests/acceptance/composer.json index a46b9c8ae9187..8d8a3f56921bf 100755 --- a/dev/tests/acceptance/composer.json +++ b/dev/tests/acceptance/composer.json @@ -22,7 +22,7 @@ "symfony/process": ">=2.7 <3.4", "henrikbjorn/lurker": "^1.2", "magento/magento2-functional-testing-framework": "~2.1.1", - "php": "7.0.2|7.0.4|~7.0.6|~7.1.0|~7.2.0", + "php": "~7.1.3||~7.2.0", "vlucas/phpdotenv": "~2.4" }, "autoload": { diff --git a/dev/tests/functional/composer.json b/dev/tests/functional/composer.json index ff38d0d01ac0e..da431fcf8a252 100644 --- a/dev/tests/functional/composer.json +++ b/dev/tests/functional/composer.json @@ -3,7 +3,7 @@ "sort-packages": true }, "require": { - "php": "7.0.2|~7.0.6|~7.1.0|~7.2.0", + "php": "~7.1.3||~7.2.0", "magento/mtf": "1.0.0-rc60", "allure-framework/allure-phpunit": "~1.2.0", "doctrine/annotations": "1.4.*", From 61674002bac5cb2510e7e335d5872fcf16bd6097 Mon Sep 17 00:00:00 2001 From: Ben Batschelet <bbatschelet@magento.com> Date: Mon, 19 Mar 2018 14:48:27 -0500 Subject: [PATCH 103/668] Fix additional calls to count() on null values --- app/code/Magento/Theme/Block/Html/Topmenu.php | 4 ++-- .../Magento/Setup/Fixtures/ConfigurableProductsFixture.php | 4 +++- .../Setup/Model/FixtureGenerator/ProductGenerator.php | 5 ++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Theme/Block/Html/Topmenu.php b/app/code/Magento/Theme/Block/Html/Topmenu.php index ed3445e117331..6c5ca39c61831 100644 --- a/app/code/Magento/Theme/Block/Html/Topmenu.php +++ b/app/code/Magento/Theme/Block/Html/Topmenu.php @@ -177,7 +177,7 @@ protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit) return $html; } - $colStops = null; + $colStops = []; if ($childLevel == 0 && $limit) { $colStops = $this->_columnBrake($child->getChildren(), $limit); } @@ -205,7 +205,7 @@ protected function _getHtml( \Magento\Framework\Data\Tree\Node $menuTree, $childrenWrapClass, $limit, - $colBrakes = [] + array $colBrakes = [] ) { $html = ''; diff --git a/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php b/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php index 938a23071feda..d87a058a0363d 100644 --- a/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php +++ b/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php @@ -722,6 +722,8 @@ private function getSearchTerms() if ($searchTerms !== null) { $searchTerms = array_key_exists(0, $searchTerms['search_term']) ? $searchTerms['search_term'] : [$searchTerms['search_term']]; + } else { + $searchTerms = []; } return $searchTerms; } @@ -845,7 +847,7 @@ private function getDescriptionClosure( $minAmountOfWordsDescription, $descriptionPrefix ) { - $count = $searchTerms === null + $count = !$searchTerms ? 0 : round( $searchTerms[$index % count($searchTerms)]['count'] * ( diff --git a/setup/src/Magento/Setup/Model/FixtureGenerator/ProductGenerator.php b/setup/src/Magento/Setup/Model/FixtureGenerator/ProductGenerator.php index baeeec92a29c8..24813302133e1 100644 --- a/setup/src/Magento/Setup/Model/FixtureGenerator/ProductGenerator.php +++ b/setup/src/Magento/Setup/Model/FixtureGenerator/ProductGenerator.php @@ -170,7 +170,10 @@ public function generate($products, $fixtureMap) ], ], ]; - if (count($fixtureMap['website_ids'](1, 0)) === 1) { + if ( + !is_array($fixtureMap['website_ids'](1, 0)) || + count($fixtureMap['website_ids'](1, 0)) === 1 + ) { // Get website id from fixture in case when one site is assigned per product $customTableMap['catalog_product_website'] = [ 'fields' => [ From 996db2cd48a7401e4404f5d58d12d82c560b2fcd Mon Sep 17 00:00:00 2001 From: Ben Batschelet <bbatschelet@magento.com> Date: Mon, 19 Mar 2018 15:26:24 -0500 Subject: [PATCH 104/668] One more place where we can use Countable interface --- app/code/Magento/Ui/DataProvider/AbstractDataProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/DataProvider/AbstractDataProvider.php b/app/code/Magento/Ui/DataProvider/AbstractDataProvider.php index cff6171395ec9..971da30d1009a 100644 --- a/app/code/Magento/Ui/DataProvider/AbstractDataProvider.php +++ b/app/code/Magento/Ui/DataProvider/AbstractDataProvider.php @@ -12,7 +12,7 @@ * @api * @since 100.0.2 */ -abstract class AbstractDataProvider implements DataProviderInterface +abstract class AbstractDataProvider implements DataProviderInterface, \Countable { /** * Data Provider name From 160505e80cd474708ce4449fd87a6699abf017bc Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Mon, 19 Mar 2018 17:04:45 -0500 Subject: [PATCH 105/668] MAGETWO-89292: Implement SDL from prototype - documentation annotation support phase 1 --- .../Magento/CatalogGraphQl/etc/schema.graphql | 10 ++++--- .../GraphQl/Config/GraphQlReader.php | 8 ++++-- .../MetaReader/FieldMetaReader.php | 26 ++++++++++++++++++ .../GraphQlReader/Reader/ObjectType.php | 27 ++++++++++++++++++- 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphql b/app/code/Magento/CatalogGraphQl/etc/schema.graphql index e144ecca0f020..6dc203693c658 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphql +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphql @@ -487,8 +487,8 @@ type SimpleProduct implements ProductInterface, PhysicalProductInterface, Custom type Products { items: [ProductInterface] - page_info: SearchResultPageInfo - total_count: Int + page_info: SearchResultPageInfo @doc(text: "An object that includes the `page_info` and `cu..") + total_count: Int @doc(text: "The number of products returned.") } @@ -532,7 +532,7 @@ input ProductFilterInput { or: ProductFilterInput } -type ProductMediaGalleryEntriesContent { +type ProductMediaGalleryEntriesContent @doc(text: "The number of products returned.") { base64_encoded_data: String type: String name: String @@ -586,7 +586,9 @@ input ProductSortInput { gift_message_available: SortEnum } -type MediaGalleryEntry { +type MediaGalleryEntry +@doc(description: "The number of products returned.") +{ id: Int media_type: String label: String diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php index be5d048cb020f..80bbff36c1672 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php @@ -9,8 +9,9 @@ use Magento\Framework\Config\FileResolverInterface; use Magento\Framework\GraphQl\Config\GraphQlReader\TypeReader; +use Magento\Framework\Config\ReaderInterface; -class GraphQlReader implements \Magento\Framework\Config\ReaderInterface +class GraphQlReader implements ReaderInterface { /** * File locator @@ -104,8 +105,11 @@ private function parseTypes($graphQlSchemaContent) : array $typeNamePattern = '[_A-Za-z][_0-9A-Za-z]*'; $typeDefinitionPattern = '.*\{[^\}]*\}'; $spacePattern = '[\s\t\n\r]*'; + $annotationsPattern = '(@.*[\s\t\n\r]*){0,}'; + preg_match_all( - "/{$typeKindsPattern}{$spacePattern}({$typeNamePattern}){$spacePattern}{$typeDefinitionPattern}/i", + "/{$typeKindsPattern}{$spacePattern}({$typeNamePattern})" + . "{$spacePattern}{$annotationsPattern}{$typeDefinitionPattern}/i", $graphQlSchemaContent, $matches ); diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php index 528cdc3f442b8..19bf9468d5b93 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php @@ -45,6 +45,10 @@ public function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMet $this->typeMetaReader->readTypeMeta($fieldTypeMeta, 'OutputField') ); + if (!empty($fieldMeta->astNode->directives) && !($fieldMeta instanceof \GraphQL\Type\Definition\ScalarType)) { + $result['description'] = $this->readTypeDescription($fieldMeta); + } + $arguments = $fieldMeta->args; foreach ($arguments as $argumentMeta) { $argumentName = $argumentMeta->name; @@ -79,4 +83,26 @@ private function readFieldResolver(\GraphQL\Type\Definition\FieldDefinition $fie } return null; } + + /** + * Read documentation annotation for a specific type + * + * @param $meta + * @return string + */ + private function readTypeDescription($meta) : string + { + /** @var \GraphQL\Language\AST\NodeList $directives */ + $directives = $meta->astNode->directives; + foreach ($directives as $directive) { + if ($directive->name->value == 'doc') { + foreach ($directive->arguments as $directiveArgument) { + if ($directiveArgument->name->value == 'description') { + return $directiveArgument->value->value; + } + } + } + } + return ''; + } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php index 35bc7fd2e4c14..d15b2759ccc24 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php @@ -36,7 +36,6 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array 'name' => $typeName, 'type' => 'graphql_type', 'fields' => [], // Populated later - ]; $interfaces = $typeMeta->getInterfaces(); @@ -53,9 +52,35 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array $result['fields'][$fieldName] = $this->fieldMetaReader->readFieldMeta($fieldMeta); } + if (!empty($typeMeta->astNode->directives) && !($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { + $result['description'] = $this->readTypeDescription($typeMeta); + } + return $result; } else { return null; } } + + /** + * Read documentation annotation for a specific type + * + * @param $meta + * @return string + */ + private function readTypeDescription($meta) : string + { + /** @var \GraphQL\Language\AST\NodeList $directives */ + $directives = $meta->astNode->directives; + foreach ($directives as $directive) { + if ($directive->name->value == 'doc') { + foreach ($directive->arguments as $directiveArgument) { + if ($directiveArgument->name->value == 'description') { + return $directiveArgument->value->value; + } + } + } + } + return ''; + } } From f4fef6fd2b1aa26697becc1ba0b84c58f20cb10b Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Mon, 19 Mar 2018 17:05:14 -0500 Subject: [PATCH 106/668] MAGETWO-89292: Implement SDL from prototype - documentation annotation support phase 1 --- app/code/Magento/CatalogGraphQl/etc/schema.graphql | 8 ++++---- app/code/Magento/GraphQl/etc/schema.graphql | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphql b/app/code/Magento/CatalogGraphQl/etc/schema.graphql index 6dc203693c658..c35997669727a 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphql +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphql @@ -487,8 +487,8 @@ type SimpleProduct implements ProductInterface, PhysicalProductInterface, Custom type Products { items: [ProductInterface] - page_info: SearchResultPageInfo @doc(text: "An object that includes the `page_info` and `cu..") - total_count: Int @doc(text: "The number of products returned.") + page_info: SearchResultPageInfo @doc(description: "comment for page_info.") + total_count: Int } @@ -532,7 +532,7 @@ input ProductFilterInput { or: ProductFilterInput } -type ProductMediaGalleryEntriesContent @doc(text: "The number of products returned.") { +type ProductMediaGalleryEntriesContent @doc(description: "The number of products returned.") { base64_encoded_data: String type: String name: String @@ -587,7 +587,7 @@ input ProductSortInput { } type MediaGalleryEntry -@doc(description: "The number of products returned.") +@doc(description: "comment for MediaGalleryEntry") { id: Int media_type: String diff --git a/app/code/Magento/GraphQl/etc/schema.graphql b/app/code/Magento/GraphQl/etc/schema.graphql index 498da368074fb..50d20f1ff769e 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphql +++ b/app/code/Magento/GraphQl/etc/schema.graphql @@ -20,7 +20,9 @@ input FilterTypeInput { nin: [String] } -type SearchResultPageInfo { +type SearchResultPageInfo +@doc(description:"Comment for SearchResultPageInfo") +{ page_size: Int current_page: Int } From ab644bee47f0c11e88f1ae6645660e113a828ed1 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@magento.com> Date: Mon, 19 Mar 2018 23:23:25 -0500 Subject: [PATCH 107/668] MAGETWO-89366: Create integration or api tests - Added introspection query test for various use cases --- .../GraphQl/GraphQlIntrospectionTest.php | 298 ++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/GraphQl/GraphQlIntrospectionTest.php diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/GraphQlIntrospectionTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/GraphQlIntrospectionTest.php new file mode 100644 index 0000000000000..a4cdcd913481c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GraphQl/GraphQlIntrospectionTest.php @@ -0,0 +1,298 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\GraphQl; + +use Magento\Framework\GraphQl\Type\Definition\InputObjectType; +use Magento\Framework\GraphQl\Type\Definition\ObjectType; +use Magento\Framework\GraphQl\Type\Definition\StringType; +use Magento\Framework\GraphQl\Type\SchemaFactory; +use Magento\Framework\ObjectManagerInterface; +use \GraphQL\Type\Definition\Type; + +class GraphQlIntrospectionTest extends \PHPUnit\Framework\TestCase +{ + + /** @var SchemaFactory */ + private $schemaFactory; + /** @var ObjectManagerInterface */ + private $objectManager; + + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->schemaFactory = $this->objectManager->create(SchemaFactory::class); + } + + public function testIntrospectionQuery() + { + $emptySchema = $this->schemaFactory->create( + [ + 'query' => new ObjectType( + [ + 'name' => 'Query', + 'fields' => ['a' => Type::string()] + ] + ) + ] + ); + $request = + <<<QUERY +query IntrospectionQuery { +__schema { +queryType { name } +types{ +...FullType +} +} +} +fragment FullType on __Type{ +name +kind +fields(includeDeprecated:true){ +name +args{ +...InputValue +} + } +} + +fragment TypeRef on __Type { +kind +name +ofType{ +kind +name +} +} +fragment InputValue on __InputValue { +name +description +type { ...TypeRef } +defaultValue +} +QUERY; + $response = \GraphQL\GraphQL::executeQuery($emptySchema, $request); + $output = $response->toArray()['data']['__schema']; + $this->assertEquals('Query', $output['queryType']['name']); + $this->assertEquals($output['types'][0]['kind'], 'OBJECT'); + $expectedFragment = + [ + 'name' => 'Query', + 'kind' => 'OBJECT', + 'fields' => [ + [ + 'name' => 'a', + 'args' => [] + ] + ] + ]; + $this->assertContains($expectedFragment, $output['types']); + } + + /** + * Tests an InputObjectType with NON Null field and description at Field level + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testIntrospectsInputObjectWithNonNullInputField() + { + $testInputObject = new InputObjectType( + [ + 'name' => 'ProductFilterInput', + 'fields' => [ + 'attributeA' =>['type' => Type::nonNull(Type::string()), 'description' =>'testDescriptionForA'], + 'attributeB' => ['type' => Type::listOf(Type::string())], + 'attributeC' => ['type' => Type::string(), 'defaultValue' => null ], + 'attributeD' => ['type' => Type::string(), 'defaultValue' => 'test', 'description' =>'testDescriptionForD'], + + ] + ] + ); + $TestType = new ObjectType([ + 'name' => 'Query', + 'fields' => [ + 'field' => [ + 'type' => Type::string(), + 'args' => ['complex' => ['type' => $testInputObject]], + 'resolve' => function ($args) { + return json_encode($args['complex']); + } + ] + ] + ]); + $testSchema = $this->schemaFactory->create( + ['query' => $TestType] + ); + + $request = + <<<QUERY +{ + __schema { + types { + kind + name + inputFields { + name + description + type { ...TypeRef } + defaultValue + } + } + } + } + fragment TypeRef on __Type { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + } + } + } +} +QUERY; + $response = \GraphQL\GraphQL::executeQuery($testSchema, $request); + $expectedResult = + [ + 'kind'=> 'INPUT_OBJECT', + 'name'=> 'ProductFilterInput', + 'inputFields'=> [ + [ + 'name'=> 'attributeA', + 'description'=> 'testDescriptionForA', + 'type'=> [ + 'kind'=> 'NON_NULL', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null + ] + ], + 'defaultValue'=> null + ], + [ + 'name'=> 'attributeB', + 'description'=> null, + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null + ] + ], + 'defaultValue'=> null + ], + [ + 'name'=> 'attributeC', + 'description'=> null, + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null + ], + 'defaultValue'=> 'null' + ], + [ + 'name'=> 'attributeD', + 'description'=> 'testDescriptionForD', + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null + ], + 'defaultValue'=> '"test"' + ] + ] + ]; + $output = $response->toArray()['data']['__schema']['types']; + $this->assertContains($expectedResult, $output); + } + + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testIntrospectsIncludeTheDeprecatedParameter() + { + $testSchema = $this->schemaFactory->create( + [ + 'query' => new ObjectType( + [ + 'name' => 'Query', + 'fields' => [ + 'deprecated' => [ + 'type' => Type::string(), + 'deprecationReason' =>'Deprecated in an older version' + ], + 'nonDeprecated' => [ + 'type' => Type::string() + ] + ] + ] + ) + ] + ); + $request = + <<<QUERY + { + __type(name:"Query") + { + name + kind + fields(includeDeprecated:true){ + name + type{ + kind + name + } + description + isDeprecated + deprecationReason + + } + } +} + +QUERY; + $response = \GraphQL\GraphQL::executeQuery($testSchema, $request); + $output = $response->toArray()['data']['__type']; + $expectedResult = + [ + "name" =>"Query", + "kind" =>"OBJECT", + "fields" => [ + [ + 'name'=> 'deprecated', + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String' + ], + 'description'=> null, + 'isDeprecated'=> true, + 'deprecationReason'=> 'Deprecated in an older version' + ], + [ + 'name'=> 'nonDeprecated', + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String' + ], + 'description'=> null, + 'isDeprecated'=> false, + 'deprecationReason'=> null + ] + ] + ]; + $this->assertEquals($expectedResult, $output); + } +} From 73099fdecc8e5ef2c5eaa4d47f5fb5cb26bb3738 Mon Sep 17 00:00:00 2001 From: Alexander Shkurko <coderimus@gmail.com> Date: Sun, 14 Jan 2018 14:59:34 +0100 Subject: [PATCH 108/668] Performance: remove count() form the condition section of a loop --- app/code/Magento/Backend/Model/Widget/Grid/Parser.php | 5 +++-- .../Catalog/Model/Layer/Filter/DataProvider/Price.php | 3 ++- .../Config/Structure/Element/Dependency/MapperTest.php | 6 ++++-- app/code/Magento/Paypal/Model/Report/Settlement.php | 3 ++- app/code/Magento/Usps/Model/Carrier.php | 3 ++- app/code/Magento/Webapi/Model/Rest/Swagger/Generator.php | 3 ++- .../Magento/Webapi/Model/Soap/Wsdl/ComplexTypeStrategy.php | 3 ++- 7 files changed, 17 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Backend/Model/Widget/Grid/Parser.php b/app/code/Magento/Backend/Model/Widget/Grid/Parser.php index e2b77fb471acd..ea6fadf49e253 100644 --- a/app/code/Magento/Backend/Model/Widget/Grid/Parser.php +++ b/app/code/Magento/Backend/Model/Widget/Grid/Parser.php @@ -30,8 +30,9 @@ public function parseExpression($expression) $expression = trim($expression); foreach ($this->_operations as $operation) { $splittedExpr = preg_split('/\\' . $operation . '/', $expression, -1, PREG_SPLIT_DELIM_CAPTURE); - if (count($splittedExpr) > 1) { - for ($i = 0; $i < count($splittedExpr); $i++) { + if (!empty($splittedExpr)) { + $count = count($splittedExpr); + for ($i = 0; $i < $count; $i++) { $stack = array_merge($stack, $this->parseExpression($splittedExpr[$i])); if ($i > 0) { $stack[] = $operation; diff --git a/app/code/Magento/Catalog/Model/Layer/Filter/DataProvider/Price.php b/app/code/Magento/Catalog/Model/Layer/Filter/DataProvider/Price.php index 8a17a3b6c8cfa..d1aee8c4c5ba6 100644 --- a/app/code/Magento/Catalog/Model/Layer/Filter/DataProvider/Price.php +++ b/app/code/Magento/Catalog/Model/Layer/Filter/DataProvider/Price.php @@ -282,7 +282,8 @@ public function getMaxPrice() public function getPriorFilters($filterParams) { $priorFilters = []; - for ($i = 1; $i < count($filterParams); ++$i) { + $count = count($filterParams); + for ($i = 1; $i < $count; ++$i) { $priorFilter = $this->validateFilter($filterParams[$i]); if ($priorFilter) { $priorFilters[] = $priorFilter; diff --git a/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/Dependency/MapperTest.php b/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/Dependency/MapperTest.php index 1c758bfcbefaa..f532e3f3d64f6 100644 --- a/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/Dependency/MapperTest.php +++ b/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/Dependency/MapperTest.php @@ -98,7 +98,8 @@ public function testGetDependenciesWhenDependentIsInvisible($isValueSatisfy) { $expected = []; $rowData = array_values($this->_testData); - for ($i = 0; $i < count($this->_testData); ++$i) { + $count = $this->_testData; + for ($i = 0; $i < $count; ++$i) { $data = $rowData[$i]; $dependentPath = 'some path ' . $i; $field = $this->_getField( @@ -158,7 +159,8 @@ public function testGetDependenciesIsVisible() { $expected = []; $rowData = array_values($this->_testData); - for ($i = 0; $i < count($this->_testData); ++$i) { + $count = count($this->_testData); + for ($i = 0; $i < $count; ++$i) { $data = $rowData[$i]; $field = $this->_getField( true, diff --git a/app/code/Magento/Paypal/Model/Report/Settlement.php b/app/code/Magento/Paypal/Model/Report/Settlement.php index 12307977d7e36..5dc51518f0b11 100644 --- a/app/code/Magento/Paypal/Model/Report/Settlement.php +++ b/app/code/Magento/Paypal/Model/Report/Settlement.php @@ -369,7 +369,8 @@ public function parseCsv($localCsv, $format = 'new') // Section columns. // In case ever the column order is changed, we will have the items recorded properly // anyway. We have named, not numbered columns. - for ($i = 1; $i < count($line); $i++) { + $count = count($line); + for ($i = 1; $i < $count; $i++) { $sectionColumns[$line[$i]] = $i; } $flippedSectionColumns = array_flip($sectionColumns); diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php index 2b46fd884f651..f56f490099bb9 100644 --- a/app/code/Magento/Usps/Model/Carrier.php +++ b/app/code/Magento/Usps/Model/Carrier.php @@ -2054,7 +2054,8 @@ protected function _parseZip($zipString, $returnFull = false) if (preg_match('/[\\d\\w]{5}\\-[\\d\\w]{4}/', $zipString) != 0) { $zip = explode('-', $zipString); } - for ($i = 0; $i < count($zip); ++$i) { + $count = count($zip); + for ($i = 0; $i < $count; ++$i) { if (strlen($zip[$i]) == 5) { $zip5 = $zip[$i]; } elseif (strlen($zip[$i]) == 4) { diff --git a/app/code/Magento/Webapi/Model/Rest/Swagger/Generator.php b/app/code/Magento/Webapi/Model/Rest/Swagger/Generator.php index 6609040b040d0..8d27ed796f437 100644 --- a/app/code/Magento/Webapi/Model/Rest/Swagger/Generator.php +++ b/app/code/Magento/Webapi/Model/Rest/Swagger/Generator.php @@ -749,7 +749,8 @@ private function handlePrimitive($name, $prefix) private function convertPathParams($uri) { $parts = explode('/', $uri); - for ($i=0; $i < count($parts); $i++) { + $count = count($parts); + for ($i=0; $i < $count; $i++) { if (strpos($parts[$i], ':') === 0) { $parts[$i] = '{' . substr($parts[$i], 1) . '}'; } diff --git a/app/code/Magento/Webapi/Model/Soap/Wsdl/ComplexTypeStrategy.php b/app/code/Magento/Webapi/Model/Soap/Wsdl/ComplexTypeStrategy.php index 401440684165c..3884a0ef026e1 100644 --- a/app/code/Magento/Webapi/Model/Soap/Wsdl/ComplexTypeStrategy.php +++ b/app/code/Magento/Webapi/Model/Soap/Wsdl/ComplexTypeStrategy.php @@ -229,7 +229,8 @@ public function addAnnotation(\DOMElement $element, $documentation, $default = n $this->_processElementType($elementType, $documentation, $appInfoNode); if (preg_match_all('/{([a-z]+):(.+)}/Ui', $documentation, $matches)) { - for ($i = 0; $i < count($matches[0]); $i++) { + $count = count($matches[0]); + for ($i = 0; $i < $count; $i++) { $appinfoTag = $matches[0][$i]; $tagName = $matches[1][$i]; $tagValue = $matches[2][$i]; From b4eede9d69f96449e3a44a2352424a578c0f998d Mon Sep 17 00:00:00 2001 From: Alexander Shkurko <coderimus@gmail.com> Date: Mon, 15 Jan 2018 14:11:50 +0100 Subject: [PATCH 109/668] Hotfix: change the way of checking array size and condition check --- app/code/Magento/Backend/Model/Widget/Grid/Parser.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Backend/Model/Widget/Grid/Parser.php b/app/code/Magento/Backend/Model/Widget/Grid/Parser.php index ea6fadf49e253..fbed7149aa565 100644 --- a/app/code/Magento/Backend/Model/Widget/Grid/Parser.php +++ b/app/code/Magento/Backend/Model/Widget/Grid/Parser.php @@ -30,8 +30,8 @@ public function parseExpression($expression) $expression = trim($expression); foreach ($this->_operations as $operation) { $splittedExpr = preg_split('/\\' . $operation . '/', $expression, -1, PREG_SPLIT_DELIM_CAPTURE); - if (!empty($splittedExpr)) { - $count = count($splittedExpr); + $count = count($splittedExpr); + if ($count > 1) { for ($i = 0; $i < $count; $i++) { $stack = array_merge($stack, $this->parseExpression($splittedExpr[$i])); if ($i > 0) { From a478f9d9c5db7a6f35f554e97d066ea7c44ba136 Mon Sep 17 00:00:00 2001 From: Alexander Shkurko <coderimus@gmail.com> Date: Mon, 15 Jan 2018 15:03:32 +0100 Subject: [PATCH 110/668] Hotfix: add missed count() --- .../Model/Config/Structure/Element/Dependency/MapperTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/Dependency/MapperTest.php b/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/Dependency/MapperTest.php index f532e3f3d64f6..2f081ea4285b9 100644 --- a/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/Dependency/MapperTest.php +++ b/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/Dependency/MapperTest.php @@ -98,7 +98,7 @@ public function testGetDependenciesWhenDependentIsInvisible($isValueSatisfy) { $expected = []; $rowData = array_values($this->_testData); - $count = $this->_testData; + $count = count($this->_testData); for ($i = 0; $i < $count; ++$i) { $data = $rowData[$i]; $dependentPath = 'some path ' . $i; From dbcd678bbb784800cda096d8b86ac36ad08025f1 Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" <a.vasiliev@sam-solutions.biz> Date: Tue, 20 Mar 2018 12:25:44 +0200 Subject: [PATCH 111/668] Testing of Travis automated tests execution --- .../Api/BulkRepositoryInterface.php | 24 +++ .../Api/Data/OperationDetailsInterface.php | 72 ++++++++ .../Data/OperationShortDetailsInterface.php | 70 ++++++++ .../Api/Data/ShortOperationListInterface.php | 23 +++ .../Model/BulkStatus.php | 159 +++++++++++++++--- .../Model/Operation.php | 16 ++ .../Model/Operation/Details.php | 113 +++++++++++-- .../Model/OperationShortDetails.php | 65 +++++++ .../Model/ShortOperationList.php | 34 ++++ .../Model/StatusMapper.php | 4 +- .../Setup/UpgradeSchema.php | 58 +++++++ .../Magento/AsynchronousOperations/etc/di.xml | 5 + .../etc/extension_attributes.xml | 15 ++ .../AsynchronousOperations/etc/webapi.xml | 18 ++ .../Framework/Bulk/OperationInterface.php | 19 +++ 15 files changed, 655 insertions(+), 40 deletions(-) create mode 100644 app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php create mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/OperationDetailsInterface.php create mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/OperationShortDetailsInterface.php create mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/ShortOperationListInterface.php create mode 100644 app/code/Magento/AsynchronousOperations/Model/OperationShortDetails.php create mode 100644 app/code/Magento/AsynchronousOperations/Model/ShortOperationList.php create mode 100755 app/code/Magento/AsynchronousOperations/Setup/UpgradeSchema.php create mode 100644 app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml create mode 100644 app/code/Magento/AsynchronousOperations/etc/webapi.xml diff --git a/app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php b/app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php new file mode 100644 index 0000000000000..47a7555287b9b --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Api; + +/** + * @api + * @since 100.3.0 + */ +interface BulkRepositoryInterface extends \Magento\Framework\Bulk\BulkStatusInterface +{ + + /** + * @param string $bulkUuid + * @return \Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @since 100.3.0 + */ + public function getBulkDetails($bulkUuid); +} diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/OperationDetailsInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/OperationDetailsInterface.php new file mode 100644 index 0000000000000..c071c556ace47 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Api/Data/OperationDetailsInterface.php @@ -0,0 +1,72 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Api\Data; + +/** + * Interface + * + * @api + * @since 100.3.0 + */ +interface OperationDetailsInterface +{ + /** + * Total operations count + * + * @return int + * @since 100.3.0 + */ + public function getOperationsTotal(); + + /** + * Open operations count + * + * @return int + * @since 100.3.0 + */ + public function getOpen(); + + /** + * Successfully completed operations count + * + * @return int + * @since 100.3.0 + */ + public function getOperationsSuccessful(); + + /** + * Total failed operations count + * + * @return int + * @since 100.3.0 + */ + public function getTotalFailed(); + + /** + * Failed not retriable operations count + * + * @return int + * @since 100.3.0 + */ + public function getFailedNotRetriable(); + + /** + * Failed retriable operations count + * + * @return int + * @since 100.3.0 + */ + public function getFailedRetriable(); + + /** + * Rejected operations count + * + * @return int + * @since 100.3.0 + */ + public function getRejected(); +} diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/OperationShortDetailsInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/OperationShortDetailsInterface.php new file mode 100644 index 0000000000000..84e96bb4905e9 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Api/Data/OperationShortDetailsInterface.php @@ -0,0 +1,70 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Api\Data; + +use \Magento\Framework\Bulk\OperationInterface; +/** + * Getter Class OperationShortDetailsInterface + * Instead of OperationInterface this class don't provide all operation data + * and not responsive to set any data, just get operation data without serialized_data + * + * @api + * @since 100.3.0 + * @see \Magento\AsynchronousOperations\Api\Data\OperationInterface + */ +interface OperationShortDetailsInterface +{ + /** + * Operation id + * + * @return int + * @since 100.3.0 + */ + public function getId(); + + /** + * Message Queue Topic + * + * @return string + * @since 100.3.0 + */ + public function getTopicName(); + + /** + * Result serialized Data + * + * @return string + * @since 100.3.0 + */ + public function getResultSerializedData(); + + /** + * Get operation status + * + * OPEN | COMPLETE | RETRIABLY_FAILED | NOT_RETRIABLY_FAILED + * + * @return int + * @since 100.3.0 + */ + public function getStatus(); + + /** + * Get result message + * + * @return string + * @since 100.3.0 + */ + public function getResultMessage(); + + /** + * Get error code + * + * @return int + * @since 100.3.0 + */ + public function getErrorCode(); +} diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/ShortOperationListInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/ShortOperationListInterface.php new file mode 100644 index 0000000000000..a5ac69a0a9eb4 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Api/Data/ShortOperationListInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Api\Data; + +/** + * List of bulk operations with short operation details. + * @api + * @since 100.3.0 + */ +interface ShortOperationListInterface +{ + /** + * Get list of operations. + * + * @return \Magento\AsynchronousOperations\Api\Data\OperationShortDetailsInterface[] + * @since 100.3.0 + */ + public function getItems(); +} diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php b/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php index c37ae0d23dd25..3134b80165652 100644 --- a/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php +++ b/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php @@ -11,6 +11,14 @@ use Magento\Framework\App\ResourceConnection; use Magento\AsynchronousOperations\Model\BulkStatus\CalculatedStatusSql; use Magento\Framework\EntityManager\MetadataPool; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Setup\Exception; +use Magento\Framework\EntityManager\EntityManager; +use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterfaceFactory; +use Magento\AsynchronousOperations\Api\Data\OperationListInterfaceFactory; +use Magento\AsynchronousOperations\Api\Data\ShortOperationListInterfaceFactory; +use Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterfaceFactory; +use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterfaceFactory; /** * Class BulkStatus @@ -43,25 +51,82 @@ class BulkStatus implements \Magento\Framework\Bulk\BulkStatusInterface private $metadataPool; /** - * BulkStatus constructor. - * @param ResourceModel\Bulk\CollectionFactory $bulkCollection - * @param ResourceModel\Operation\CollectionFactory $operationCollection - * @param ResourceConnection $resourceConnection - * @param CalculatedStatusSql $calculatedStatusSql - * @param MetadataPool $metadataPool + * @var \Magento\AsynchronousOperations\Model\ResourceModel\Bulk + */ + private $bulkResourceModel; + + /** + * @var \Magento\AsynchronousOperations\Model\BulkSummaryFactory + */ + private $bulkSummaryFactory; + + /** + * @var EntityManager + */ + private $entityManager; + + /** + * @var \Magento\AsynchronousOperations\Api\Data\OperationListInterfaceFactory + */ + private $operationListInterfaceFactory; + + /** + * @var \Magento\AsynchronousOperations\Api\Data\ShortOperationListInterfaceFactory + */ + private $shortOperationListFactory; + + /** + * @var \Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterfaceFactory + */ + private $bulkSummaryExtensionInterfaceFactory; + + /** + * @var \Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface + */ + private $operationDetailsFactory; + + /** + * Init dependencies. + * + * @param \Magento\AsynchronousOperations\Model\ResourceModel\Bulk\CollectionFactory $bulkCollection + * @param \Magento\AsynchronousOperations\Model\ResourceModel\Operation\CollectionFactory $operationCollection + * @param \Magento\Framework\App\ResourceConnection $resourceConnection + * @param \Magento\AsynchronousOperations\Model\BulkStatus\CalculatedStatusSql $calculatedStatusSql + * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool + * @param \Magento\AsynchronousOperations\Model\ResourceModel\Bulk $bulkResourceModel + * @param \Magento\AsynchronousOperations\Api\Data\BulkSummaryInterfaceFactory $bulkSummaryFactory + * @param \Magento\Framework\EntityManager\EntityManager $entityManager + * @param \Magento\AsynchronousOperations\Api\Data\OperationListInterfaceFactory $operationListInterfaceFactory + * @param \Magento\AsynchronousOperations\Api\Data\ShortOperationListInterfaceFactory $shortOperationListFactory + * @param \Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterfaceFactory $bulkSummaryExtensionInterfaceFactory + * @param \Magento\AsynchronousOperations\Api\Data\OperationDetailsInterfaceFactory $operationDetails */ public function __construct( \Magento\AsynchronousOperations\Model\ResourceModel\Bulk\CollectionFactory $bulkCollection, \Magento\AsynchronousOperations\Model\ResourceModel\Operation\CollectionFactory $operationCollection, ResourceConnection $resourceConnection, CalculatedStatusSql $calculatedStatusSql, - MetadataPool $metadataPool + MetadataPool $metadataPool, + \Magento\AsynchronousOperations\Model\ResourceModel\Bulk $bulkResourceModel, + BulkSummaryInterfaceFactory $bulkSummaryFactory, + EntityManager $entityManager, + OperationListInterfaceFactory $operationListInterfaceFactory, + ShortOperationListInterfaceFactory $shortOperationListFactory, + BulkSummaryExtensionInterfaceFactory $bulkSummaryExtensionInterfaceFactory, + OperationDetailsInterfaceFactory $operationDetails ) { $this->operationCollectionFactory = $operationCollection; $this->bulkCollectionFactory = $bulkCollection; $this->resourceConnection = $resourceConnection; $this->calculatedStatusSql = $calculatedStatusSql; $this->metadataPool = $metadataPool; + $this->bulkResourceModel = $bulkResourceModel; + $this->bulkSummaryFactory = $bulkSummaryFactory; + $this->entityManager = $entityManager; + $this->operationListInterfaceFactory = $operationListInterfaceFactory; + $this->bulkSummaryExtensionInterfaceFactory = $bulkSummaryExtensionInterfaceFactory; + $this->shortOperationListFactory = $shortOperationListFactory; + $this->operationDetailsFactory = $operationDetails; } /** @@ -73,12 +138,13 @@ public function getFailedOperationsByBulkId($bulkUuid, $failureType = null) ? [$failureType] : [ OperationInterface::STATUS_TYPE_RETRIABLY_FAILED, - OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED + OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED, ]; $operations = $this->operationCollectionFactory->create() - ->addFieldToFilter('bulk_uuid', $bulkUuid) - ->addFieldToFilter('status', $failureCodes) - ->getItems(); + ->addFieldToFilter('bulk_uuid', $bulkUuid) + ->addFieldToFilter('status', $failureCodes) + ->getItems(); + return $operations; } @@ -97,17 +163,21 @@ public function getOperationsCountByBulkIdAndStatus($bulkUuid, $status) * Number of operations that has been processed (i.e. operations with any status but 'open') */ $allProcessedOperationsQty = (int)$this->operationCollectionFactory->create() - ->addFieldToFilter('bulk_uuid', $bulkUuid) - ->getSize(); + ->addFieldToFilter( + 'bulk_uuid', + $bulkUuid + ) + ->getSize(); return $allOperationsQty - $allProcessedOperationsQty; } /** @var \Magento\AsynchronousOperations\Model\ResourceModel\Operation\Collection $collection */ $collection = $this->operationCollectionFactory->create(); + return $collection->addFieldToFilter('bulk_uuid', $bulkUuid) - ->addFieldToFilter('status', $status) - ->getSize(); + ->addFieldToFilter('status', $status) + ->getSize(); } /** @@ -123,13 +193,13 @@ public function getBulksByUser($userId) OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED, BulkSummaryInterface::NOT_STARTED, OperationInterface::STATUS_TYPE_OPEN, - OperationInterface::STATUS_TYPE_COMPLETE + OperationInterface::STATUS_TYPE_COMPLETE, ]; $select = $collection->getSelect(); $select->columns(['status' => $this->calculatedStatusSql->get($operationTableName)]) - ->order(new \Zend_Db_Expr('FIELD(status, ' . implode(',', $statusesArray) . ')')); + ->order(new \Zend_Db_Expr('FIELD(status, ' . implode(',', $statusesArray) . ')')); $collection->addFieldToFilter('user_id', $userId) - ->addOrder('start_time'); + ->addOrder('start_time'); return $collection->getItems(); } @@ -143,8 +213,8 @@ public function getBulkStatus($bulkUuid) * Number of operations that has been processed (i.e. operations with any status but 'open') */ $allProcessedOperationsQty = (int)$this->operationCollectionFactory->create() - ->addFieldToFilter('bulk_uuid', $bulkUuid) - ->getSize(); + ->addFieldToFilter('bulk_uuid', $bulkUuid) + ->getSize(); if ($allProcessedOperationsQty == 0) { return BulkSummaryInterface::NOT_STARTED; @@ -164,10 +234,12 @@ public function getBulkStatus($bulkUuid) * Number of operations that has been completed successfully */ $allCompleteOperationsQty = $this->operationCollectionFactory->create() - ->addFieldToFilter('bulk_uuid', $bulkUuid)->addFieldToFilter( - 'status', - OperationInterface::STATUS_TYPE_COMPLETE - )->getSize(); + ->addFieldToFilter('bulk_uuid', $bulkUuid) + ->addFieldToFilter( + 'status', + OperationInterface::STATUS_TYPE_COMPLETE + ) + ->getSize(); if ($allCompleteOperationsQty == $allOperationsQty) { return BulkSummaryInterface::FINISHED_SUCCESSFULLY; @@ -193,8 +265,43 @@ private function getOperationCount($bulkUuid) return (int)$connection->fetchOne( $connection->select() - ->from($metadata->getEntityTable(), 'operation_count') - ->where('uuid = ?', $bulkUuid) + ->from($metadata->getEntityTable(), 'operation_count') + ->where('uuid = ?', $bulkUuid) ); } + + /** + * @inheritDoc + */ + public function getBulkDetails($bulkUuid) + { + $bulkSummary = $this->bulkSummaryFactory->create(); + + /** @var \Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface $bulk */ + $bulk = $this->entityManager->load($bulkSummary, $bulkUuid); + + if ($bulk->getBulkId() === null) { + throw new \Magento\Framework\Exception\NoSuchEntityException( + __( + 'Bulk uuid %bulkUuid not exist', + ['bulkUuid' => $bulkUuid] + ) + ); + } + + $operations = $this->operationCollectionFactory->create()->addFieldToFilter('bulk_uuid', $bulkUuid)->getItems(); + $operationList = $this->shortOperationListFactory->create(['items' => $operations]); + + /** @var \Magento\AsynchronousOperations\Model\Operation\Details $operationDetails */ + $operationDetails = $this->operationDetailsFactory->create(['bulkUuid' => $bulkUuid]); + + /** @var \Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterface $bulkExtensionAttribute */ + $bulkExtensionAttribute = $this->bulkSummaryExtensionInterfaceFactory->create(); + $bulkExtensionAttribute->setOperationsList($operationList); + + $bulkExtensionAttribute->setOperationsCount($operationDetails); + $bulk->setExtensionAttributes($bulkExtensionAttribute); + + return $bulk; + } } diff --git a/app/code/Magento/AsynchronousOperations/Model/Operation.php b/app/code/Magento/AsynchronousOperations/Model/Operation.php index dbfce3ccd8b1c..31488c5d900ed 100644 --- a/app/code/Magento/AsynchronousOperations/Model/Operation.php +++ b/app/code/Magento/AsynchronousOperations/Model/Operation.php @@ -78,6 +78,22 @@ public function setSerializedData($serializedData) return $this->setData(self::SERIALIZED_DATA, $serializedData); } + /** + * @inheritDoc + */ + public function getResultSerializedData() + { + return $this->getData(self::RESULT_SERIALIZED_DATA); + } + + /** + * @inheritDoc + */ + public function setResultSerializedData($resultSerializedData) + { + return $this->setData(self::RESULT_SERIALIZED_DATA, $resultSerializedData); + } + /** * @inheritDoc */ diff --git a/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php b/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php index 398934f093350..2faa4e32abf95 100644 --- a/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php +++ b/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php @@ -3,11 +3,13 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\AsynchronousOperations\Model\Operation; +use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface; use Magento\Framework\Bulk\OperationInterface; -class Details +class Details implements OperationDetailsInterface { /** * @var array @@ -19,23 +21,33 @@ class Details */ private $bulkStatus; + /** + * @var null + */ + private $bulkUuid; + /** * Map between status codes and human readable indexes + * * @var array */ private $statusMap = [ - OperationInterface::STATUS_TYPE_COMPLETE => 'operations_successful', - OperationInterface::STATUS_TYPE_RETRIABLY_FAILED => 'failed_retriable', + OperationInterface::STATUS_TYPE_COMPLETE => 'operations_successful', + OperationInterface::STATUS_TYPE_RETRIABLY_FAILED => 'failed_retriable', OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED => 'failed_not_retriable', + OperationInterface::STATUS_TYPE_OPEN => 'open', + OperationInterface::STATUS_TYPE_REJECTED => 'rejected', ]; /** * @param \Magento\Framework\Bulk\BulkStatusInterface $bulkStatus */ public function __construct( - \Magento\Framework\Bulk\BulkStatusInterface $bulkStatus + \Magento\Framework\Bulk\BulkStatusInterface $bulkStatus, + $bulkUuid = null ) { $this->bulkStatus = $bulkStatus; + $this->bulkUuid = $bulkUuid; } /** @@ -47,11 +59,12 @@ public function __construct( public function getDetails($bulkUuid) { $details = [ - 'operations_total' => 0, + 'operations_total' => 0, 'operations_successful' => 0, - 'operations_failed' => 0, - 'failed_retriable' => 0, - 'failed_not_retriable' => 0, + 'operations_failed' => 0, + 'failed_retriable' => 0, + 'failed_not_retriable' => 0, + 'rejected' => 0, ]; if (array_key_exists($bulkUuid, $this->operationCache)) { @@ -65,13 +78,87 @@ public function getDetails($bulkUuid) ); } - // total is sum of successful, retriable, not retriable and open operations - $details['operations_total'] = array_sum($details) + $this->bulkStatus->getOperationsCountByBulkIdAndStatus( - $bulkUuid, - OperationInterface::STATUS_TYPE_OPEN - ); + // total is sum of successful, rejected, retriable, not retriable and open operations + $details['operations_total'] = + array_sum($details) + $this->bulkStatus->getOperationsCountByBulkIdAndStatus( + $bulkUuid, + OperationInterface::STATUS_TYPE_OPEN + ); $details['operations_failed'] = $details['failed_retriable'] + $details['failed_not_retriable']; $this->operationCache[$bulkUuid] = $details; + return $details; } + + /** + * @inheritDoc + */ + public function getOperationsTotal() + { + $this->getDetails($this->bulkUuid); + return $this->operationCache[$this->bulkUuid]['operations_total']; + } + + /** + * @inheritDoc + */ + public function getOpen() + { + $this->getDetails($this->bulkUuid); + $statusKey = $this->statusMap[OperationInterface::STATUS_TYPE_OPEN]; + + return $this->operationCache[$this->bulkUuid][$statusKey]; + } + + /** + * @inheritDoc + */ + public function getOperationsSuccessful() + { + $this->getDetails($this->bulkUuid); + $statusKey = $this->statusMap[OperationInterface::STATUS_TYPE_COMPLETE]; + + return $this->operationCache[$this->bulkUuid][$statusKey]; + } + + /** + * @inheritDoc + */ + public function getTotalFailed() + { + $this->getDetails($this->bulkUuid); + return $this->operationCache[$this->bulkUuid]['operations_failed']; + } + + /** + * @inheritDoc + */ + public function getFailedNotRetriable() + { + $statusKey = $this->statusMap[OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED]; + + return $this->operationCache[$this->bulkUuid][$statusKey]; + } + + /** + * @inheritDoc + */ + public function getFailedRetriable() + { + $this->getDetails($this->bulkUuid); + $statusKey = $this->statusMap[OperationInterface::STATUS_TYPE_RETRIABLY_FAILED]; + + return $this->operationCache[$this->bulkUuid][$statusKey]; + } + + /** + * @inheritDoc + */ + public function getRejected() + { + $this->getDetails($this->bulkUuid); + $statusKey = $this->statusMap[OperationInterface::STATUS_TYPE_REJECTED]; + + return $this->operationCache[$this->bulkUuid][$statusKey]; + } } diff --git a/app/code/Magento/AsynchronousOperations/Model/OperationShortDetails.php b/app/code/Magento/AsynchronousOperations/Model/OperationShortDetails.php new file mode 100644 index 0000000000000..818a72bc4920b --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Model/OperationShortDetails.php @@ -0,0 +1,65 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\AsynchronousOperations\Model; + +use Magento\AsynchronousOperations\Api\Data\OperationInterface; +use Magento\AsynchronousOperations\Api\Data\OperationShortDetailsInterface; +use Magento\Framework\DataObject; +use Magento\Framework\Api\ExtensibleDataInterface; + +/** + * Class OperationShortDetails + */ +class OperationShortDetails extends DataObject implements OperationShortDetailsInterface, ExtensibleDataInterface +{ + /** + * @inheritDoc + */ + public function getId() + { + return $this->getData(OperationInterface::ID); + } + + /** + * @inheritDoc + */ + public function getTopicName() + { + return $this->getData(OperationInterface::TOPIC_NAME); + } + + /** + * @inheritDoc + */ + public function getResultSerializedData() + { + return $this->getData(OperationInterface::RESULT_SERIALIZED_DATA); + } + + /** + * @inheritDoc + */ + public function getStatus() + { + return $this->getData(OperationInterface::STATUS); + } + + /** + * @inheritDoc + */ + public function getResultMessage() + { + return $this->getData(OperationInterface::RESULT_MESSAGE); + } + + /** + * @inheritDoc + */ + public function getErrorCode() + { + return $this->getData(OperationInterface::ERROR_CODE); + } +} diff --git a/app/code/Magento/AsynchronousOperations/Model/ShortOperationList.php b/app/code/Magento/AsynchronousOperations/Model/ShortOperationList.php new file mode 100644 index 0000000000000..7db033b92a068 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Model/ShortOperationList.php @@ -0,0 +1,34 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Model; + +/** + * List of bulk operations with short operation details and counter of operations. + */ +class ShortOperationList implements \Magento\AsynchronousOperations\Api\Data\ShortOperationListInterface +{ + /** + * @var array + */ + private $items; + + /** + * @param array $items [optional] + */ + public function __construct(array $items = []) + { + $this->items = $items; + } + + /** + * @inheritdoc + */ + public function getItems() + { + return $this->items; + } +} diff --git a/app/code/Magento/AsynchronousOperations/Model/StatusMapper.php b/app/code/Magento/AsynchronousOperations/Model/StatusMapper.php index 3ad260cf26a8a..e5aee6d2f59fa 100644 --- a/app/code/Magento/AsynchronousOperations/Model/StatusMapper.php +++ b/app/code/Magento/AsynchronousOperations/Model/StatusMapper.php @@ -25,6 +25,7 @@ public function operationStatusToBulkSummaryStatus($operationStatus) $statusMapping = [ OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED => BulkSummaryInterface::FINISHED_WITH_FAILURE, OperationInterface::STATUS_TYPE_RETRIABLY_FAILED => BulkSummaryInterface::FINISHED_WITH_FAILURE, + OperationInterface::STATUS_TYPE_REJECTED => BulkSummaryInterface::FINISHED_WITH_FAILURE, OperationInterface::STATUS_TYPE_COMPLETE => BulkSummaryInterface::FINISHED_SUCCESSFULLY, OperationInterface::STATUS_TYPE_OPEN => BulkSummaryInterface::IN_PROGRESS, BulkSummaryInterface::NOT_STARTED => BulkSummaryInterface::NOT_STARTED @@ -47,7 +48,8 @@ public function bulkSummaryStatusToOperationStatus($bulkStatus) $statusMapping = [ BulkSummaryInterface::FINISHED_WITH_FAILURE => [ OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED, - OperationInterface::STATUS_TYPE_RETRIABLY_FAILED + OperationInterface::STATUS_TYPE_RETRIABLY_FAILED, + OperationInterface::STATUS_TYPE_REJECTED ], BulkSummaryInterface::FINISHED_SUCCESSFULLY => OperationInterface::STATUS_TYPE_COMPLETE, BulkSummaryInterface::IN_PROGRESS => OperationInterface::STATUS_TYPE_OPEN, diff --git a/app/code/Magento/AsynchronousOperations/Setup/UpgradeSchema.php b/app/code/Magento/AsynchronousOperations/Setup/UpgradeSchema.php new file mode 100755 index 0000000000000..21286538e70b2 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Setup/UpgradeSchema.php @@ -0,0 +1,58 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Setup; + +use Magento\Framework\Setup\ModuleContextInterface; +use Magento\Framework\Setup\SchemaSetupInterface; +use Magento\Framework\Setup\UpgradeSchemaInterface; +use Magento\Framework\DB\Ddl\Table; + +/** + * Upgrade the AsynchronousOperations module DB scheme + */ +class UpgradeSchema implements UpgradeSchemaInterface +{ + /** + * {@inheritdoc} + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context) + { + $setup->startSetup(); + if (version_compare($context->getVersion(), '2.0.1', '<')) { + $this->addResultSerializedDataColumn($setup); + } + + $setup->endSetup(); + } + + /** + * Add the column 'result_serialized_data' to the Bulk Operation table. + * + * @param SchemaSetupInterface $setup + * @return void + */ + private function addResultSerializedDataColumn(SchemaSetupInterface $setup) + { + $connection = $setup->getConnection(); + $tableName = $setup->getTable('magento_operation'); + if (!$connection->tableColumnExists($tableName, 'result_serialized_data')) { + $connection->addColumn( + $tableName, + 'result_serialized_data', + [ + 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_BLOB, + 'size' => 0, + 'nullable' => true, + 'comment' => 'Result data (serialized) after perform an operation', + ] + ); + } + } +} diff --git a/app/code/Magento/AsynchronousOperations/etc/di.xml b/app/code/Magento/AsynchronousOperations/etc/di.xml index 3a4225347eeb3..a76f493f23e59 100644 --- a/app/code/Magento/AsynchronousOperations/etc/di.xml +++ b/app/code/Magento/AsynchronousOperations/etc/di.xml @@ -12,6 +12,9 @@ <preference for="Magento\Framework\Bulk\BulkManagementInterface" type="Magento\AsynchronousOperations\Model\BulkManagement" /> <preference for="Magento\Framework\Bulk\BulkStatusInterface" type="Magento\AsynchronousOperations\Model\BulkStatus" /> <preference for="Magento\Framework\Bulk\OperationManagementInterface" type="Magento\AsynchronousOperations\Model\OperationManagement" /> + <preference for="Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface" type="Magento\AsynchronousOperations\Model\Operation\Details" /> + <preference for="Magento\AsynchronousOperations\Api\Data\OperationShortDetailsInterface" type="Magento\AsynchronousOperations\Model\OperationShortDetails" /> + <preference for="Magento\AsynchronousOperations\Api\Data\ShortOperationListInterface" type="Magento\AsynchronousOperations\Model\ShortOperationList" /> <type name="Magento\Framework\EntityManager\MetadataPool"> <arguments> <argument name="metadata" xsi:type="array"> @@ -76,4 +79,6 @@ </type> <virtualType name="Magento\AsynchronousOperations\Ui\Component\DataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider"/> + + <preference for="Magento\AsynchronousOperations\Api\BulkRepositoryInterface" type="Magento\Framework\Bulk\BulkStatusInterface" /> </config> diff --git a/app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml b/app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml new file mode 100644 index 0000000000000..7179012d440d9 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd"> + <extension_attributes for="Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface"> + <attribute code="operations_list" type="Magento\AsynchronousOperations\Api\Data\ShortOperationListInterface" /> + </extension_attributes> + <extension_attributes for="Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface"> + <attribute code="operations_count" type="Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface" /> + </extension_attributes> +</config> diff --git a/app/code/Magento/AsynchronousOperations/etc/webapi.xml b/app/code/Magento/AsynchronousOperations/etc/webapi.xml new file mode 100644 index 0000000000000..6317387ee953d --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/etc/webapi.xml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd"> + + <route url="/V1/bulk/status/:bulkUuid" method="GET"> + <service class="Magento\AsynchronousOperations\Api\BulkRepositoryInterface" method="getBulkDetails"/> + <resources> + <resource ref="Magento_Logging::system_magento_logging_bulk_operations" /> + </resources> + </route> + +</routes> diff --git a/lib/internal/Magento/Framework/Bulk/OperationInterface.php b/lib/internal/Magento/Framework/Bulk/OperationInterface.php index c6d714b0363bd..4b626ac659626 100644 --- a/lib/internal/Magento/Framework/Bulk/OperationInterface.php +++ b/lib/internal/Magento/Framework/Bulk/OperationInterface.php @@ -19,6 +19,7 @@ interface OperationInterface const BULK_ID = 'bulk_uuid'; const TOPIC_NAME = 'topic_name'; const SERIALIZED_DATA = 'serialized_data'; + const RESULT_SERIALIZED_DATA = 'result_serialized_data'; const STATUS = 'status'; const RESULT_MESSAGE = 'result_message'; const ERROR_CODE = 'error_code'; @@ -31,6 +32,7 @@ interface OperationInterface const STATUS_TYPE_RETRIABLY_FAILED = 2; const STATUS_TYPE_NOT_RETRIABLY_FAILED = 3; const STATUS_TYPE_OPEN = 4; + const STATUS_TYPE_REJECTED = 5; /**#@-*/ /** @@ -101,6 +103,23 @@ public function getSerializedData(); */ public function setSerializedData($serializedData); + /** + * Result serialized Data + * + * @return string + * @since 100.3.0 + */ + public function getResultSerializedData(); + + /** + * Set result serialized data + * + * @param string $resultSerializedData + * @return $this + * @since 100.3.0 + */ + public function setResultSerializedData($resultSerializedData); + /** * Get operation status * From 330044785736b30795d39020385e3c9f21d84e4c Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" <a.vasiliev@sam-solutions.biz> Date: Tue, 20 Mar 2018 12:25:44 +0200 Subject: [PATCH 112/668] Bulk api status endpoint and implementation --- .../Api/BulkRepositoryInterface.php | 24 +++ .../Api/Data/OperationDetailsInterface.php | 72 ++++++++ .../Data/OperationShortDetailsInterface.php | 70 ++++++++ .../Api/Data/ShortOperationListInterface.php | 23 +++ .../Model/BulkStatus.php | 159 +++++++++++++++--- .../Model/Operation.php | 16 ++ .../Model/Operation/Details.php | 113 +++++++++++-- .../Model/OperationShortDetails.php | 65 +++++++ .../Model/ShortOperationList.php | 34 ++++ .../Model/StatusMapper.php | 4 +- .../Setup/UpgradeSchema.php | 58 +++++++ .../Magento/AsynchronousOperations/etc/di.xml | 5 + .../etc/extension_attributes.xml | 15 ++ .../AsynchronousOperations/etc/webapi.xml | 18 ++ .../Framework/Bulk/OperationInterface.php | 19 +++ 15 files changed, 655 insertions(+), 40 deletions(-) create mode 100644 app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php create mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/OperationDetailsInterface.php create mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/OperationShortDetailsInterface.php create mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/ShortOperationListInterface.php create mode 100644 app/code/Magento/AsynchronousOperations/Model/OperationShortDetails.php create mode 100644 app/code/Magento/AsynchronousOperations/Model/ShortOperationList.php create mode 100755 app/code/Magento/AsynchronousOperations/Setup/UpgradeSchema.php create mode 100644 app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml create mode 100644 app/code/Magento/AsynchronousOperations/etc/webapi.xml diff --git a/app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php b/app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php new file mode 100644 index 0000000000000..47a7555287b9b --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Api; + +/** + * @api + * @since 100.3.0 + */ +interface BulkRepositoryInterface extends \Magento\Framework\Bulk\BulkStatusInterface +{ + + /** + * @param string $bulkUuid + * @return \Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @since 100.3.0 + */ + public function getBulkDetails($bulkUuid); +} diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/OperationDetailsInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/OperationDetailsInterface.php new file mode 100644 index 0000000000000..c071c556ace47 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Api/Data/OperationDetailsInterface.php @@ -0,0 +1,72 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Api\Data; + +/** + * Interface + * + * @api + * @since 100.3.0 + */ +interface OperationDetailsInterface +{ + /** + * Total operations count + * + * @return int + * @since 100.3.0 + */ + public function getOperationsTotal(); + + /** + * Open operations count + * + * @return int + * @since 100.3.0 + */ + public function getOpen(); + + /** + * Successfully completed operations count + * + * @return int + * @since 100.3.0 + */ + public function getOperationsSuccessful(); + + /** + * Total failed operations count + * + * @return int + * @since 100.3.0 + */ + public function getTotalFailed(); + + /** + * Failed not retriable operations count + * + * @return int + * @since 100.3.0 + */ + public function getFailedNotRetriable(); + + /** + * Failed retriable operations count + * + * @return int + * @since 100.3.0 + */ + public function getFailedRetriable(); + + /** + * Rejected operations count + * + * @return int + * @since 100.3.0 + */ + public function getRejected(); +} diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/OperationShortDetailsInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/OperationShortDetailsInterface.php new file mode 100644 index 0000000000000..84e96bb4905e9 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Api/Data/OperationShortDetailsInterface.php @@ -0,0 +1,70 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Api\Data; + +use \Magento\Framework\Bulk\OperationInterface; +/** + * Getter Class OperationShortDetailsInterface + * Instead of OperationInterface this class don't provide all operation data + * and not responsive to set any data, just get operation data without serialized_data + * + * @api + * @since 100.3.0 + * @see \Magento\AsynchronousOperations\Api\Data\OperationInterface + */ +interface OperationShortDetailsInterface +{ + /** + * Operation id + * + * @return int + * @since 100.3.0 + */ + public function getId(); + + /** + * Message Queue Topic + * + * @return string + * @since 100.3.0 + */ + public function getTopicName(); + + /** + * Result serialized Data + * + * @return string + * @since 100.3.0 + */ + public function getResultSerializedData(); + + /** + * Get operation status + * + * OPEN | COMPLETE | RETRIABLY_FAILED | NOT_RETRIABLY_FAILED + * + * @return int + * @since 100.3.0 + */ + public function getStatus(); + + /** + * Get result message + * + * @return string + * @since 100.3.0 + */ + public function getResultMessage(); + + /** + * Get error code + * + * @return int + * @since 100.3.0 + */ + public function getErrorCode(); +} diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/ShortOperationListInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/ShortOperationListInterface.php new file mode 100644 index 0000000000000..a5ac69a0a9eb4 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Api/Data/ShortOperationListInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Api\Data; + +/** + * List of bulk operations with short operation details. + * @api + * @since 100.3.0 + */ +interface ShortOperationListInterface +{ + /** + * Get list of operations. + * + * @return \Magento\AsynchronousOperations\Api\Data\OperationShortDetailsInterface[] + * @since 100.3.0 + */ + public function getItems(); +} diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php b/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php index c37ae0d23dd25..3134b80165652 100644 --- a/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php +++ b/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php @@ -11,6 +11,14 @@ use Magento\Framework\App\ResourceConnection; use Magento\AsynchronousOperations\Model\BulkStatus\CalculatedStatusSql; use Magento\Framework\EntityManager\MetadataPool; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Setup\Exception; +use Magento\Framework\EntityManager\EntityManager; +use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterfaceFactory; +use Magento\AsynchronousOperations\Api\Data\OperationListInterfaceFactory; +use Magento\AsynchronousOperations\Api\Data\ShortOperationListInterfaceFactory; +use Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterfaceFactory; +use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterfaceFactory; /** * Class BulkStatus @@ -43,25 +51,82 @@ class BulkStatus implements \Magento\Framework\Bulk\BulkStatusInterface private $metadataPool; /** - * BulkStatus constructor. - * @param ResourceModel\Bulk\CollectionFactory $bulkCollection - * @param ResourceModel\Operation\CollectionFactory $operationCollection - * @param ResourceConnection $resourceConnection - * @param CalculatedStatusSql $calculatedStatusSql - * @param MetadataPool $metadataPool + * @var \Magento\AsynchronousOperations\Model\ResourceModel\Bulk + */ + private $bulkResourceModel; + + /** + * @var \Magento\AsynchronousOperations\Model\BulkSummaryFactory + */ + private $bulkSummaryFactory; + + /** + * @var EntityManager + */ + private $entityManager; + + /** + * @var \Magento\AsynchronousOperations\Api\Data\OperationListInterfaceFactory + */ + private $operationListInterfaceFactory; + + /** + * @var \Magento\AsynchronousOperations\Api\Data\ShortOperationListInterfaceFactory + */ + private $shortOperationListFactory; + + /** + * @var \Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterfaceFactory + */ + private $bulkSummaryExtensionInterfaceFactory; + + /** + * @var \Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface + */ + private $operationDetailsFactory; + + /** + * Init dependencies. + * + * @param \Magento\AsynchronousOperations\Model\ResourceModel\Bulk\CollectionFactory $bulkCollection + * @param \Magento\AsynchronousOperations\Model\ResourceModel\Operation\CollectionFactory $operationCollection + * @param \Magento\Framework\App\ResourceConnection $resourceConnection + * @param \Magento\AsynchronousOperations\Model\BulkStatus\CalculatedStatusSql $calculatedStatusSql + * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool + * @param \Magento\AsynchronousOperations\Model\ResourceModel\Bulk $bulkResourceModel + * @param \Magento\AsynchronousOperations\Api\Data\BulkSummaryInterfaceFactory $bulkSummaryFactory + * @param \Magento\Framework\EntityManager\EntityManager $entityManager + * @param \Magento\AsynchronousOperations\Api\Data\OperationListInterfaceFactory $operationListInterfaceFactory + * @param \Magento\AsynchronousOperations\Api\Data\ShortOperationListInterfaceFactory $shortOperationListFactory + * @param \Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterfaceFactory $bulkSummaryExtensionInterfaceFactory + * @param \Magento\AsynchronousOperations\Api\Data\OperationDetailsInterfaceFactory $operationDetails */ public function __construct( \Magento\AsynchronousOperations\Model\ResourceModel\Bulk\CollectionFactory $bulkCollection, \Magento\AsynchronousOperations\Model\ResourceModel\Operation\CollectionFactory $operationCollection, ResourceConnection $resourceConnection, CalculatedStatusSql $calculatedStatusSql, - MetadataPool $metadataPool + MetadataPool $metadataPool, + \Magento\AsynchronousOperations\Model\ResourceModel\Bulk $bulkResourceModel, + BulkSummaryInterfaceFactory $bulkSummaryFactory, + EntityManager $entityManager, + OperationListInterfaceFactory $operationListInterfaceFactory, + ShortOperationListInterfaceFactory $shortOperationListFactory, + BulkSummaryExtensionInterfaceFactory $bulkSummaryExtensionInterfaceFactory, + OperationDetailsInterfaceFactory $operationDetails ) { $this->operationCollectionFactory = $operationCollection; $this->bulkCollectionFactory = $bulkCollection; $this->resourceConnection = $resourceConnection; $this->calculatedStatusSql = $calculatedStatusSql; $this->metadataPool = $metadataPool; + $this->bulkResourceModel = $bulkResourceModel; + $this->bulkSummaryFactory = $bulkSummaryFactory; + $this->entityManager = $entityManager; + $this->operationListInterfaceFactory = $operationListInterfaceFactory; + $this->bulkSummaryExtensionInterfaceFactory = $bulkSummaryExtensionInterfaceFactory; + $this->shortOperationListFactory = $shortOperationListFactory; + $this->operationDetailsFactory = $operationDetails; } /** @@ -73,12 +138,13 @@ public function getFailedOperationsByBulkId($bulkUuid, $failureType = null) ? [$failureType] : [ OperationInterface::STATUS_TYPE_RETRIABLY_FAILED, - OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED + OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED, ]; $operations = $this->operationCollectionFactory->create() - ->addFieldToFilter('bulk_uuid', $bulkUuid) - ->addFieldToFilter('status', $failureCodes) - ->getItems(); + ->addFieldToFilter('bulk_uuid', $bulkUuid) + ->addFieldToFilter('status', $failureCodes) + ->getItems(); + return $operations; } @@ -97,17 +163,21 @@ public function getOperationsCountByBulkIdAndStatus($bulkUuid, $status) * Number of operations that has been processed (i.e. operations with any status but 'open') */ $allProcessedOperationsQty = (int)$this->operationCollectionFactory->create() - ->addFieldToFilter('bulk_uuid', $bulkUuid) - ->getSize(); + ->addFieldToFilter( + 'bulk_uuid', + $bulkUuid + ) + ->getSize(); return $allOperationsQty - $allProcessedOperationsQty; } /** @var \Magento\AsynchronousOperations\Model\ResourceModel\Operation\Collection $collection */ $collection = $this->operationCollectionFactory->create(); + return $collection->addFieldToFilter('bulk_uuid', $bulkUuid) - ->addFieldToFilter('status', $status) - ->getSize(); + ->addFieldToFilter('status', $status) + ->getSize(); } /** @@ -123,13 +193,13 @@ public function getBulksByUser($userId) OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED, BulkSummaryInterface::NOT_STARTED, OperationInterface::STATUS_TYPE_OPEN, - OperationInterface::STATUS_TYPE_COMPLETE + OperationInterface::STATUS_TYPE_COMPLETE, ]; $select = $collection->getSelect(); $select->columns(['status' => $this->calculatedStatusSql->get($operationTableName)]) - ->order(new \Zend_Db_Expr('FIELD(status, ' . implode(',', $statusesArray) . ')')); + ->order(new \Zend_Db_Expr('FIELD(status, ' . implode(',', $statusesArray) . ')')); $collection->addFieldToFilter('user_id', $userId) - ->addOrder('start_time'); + ->addOrder('start_time'); return $collection->getItems(); } @@ -143,8 +213,8 @@ public function getBulkStatus($bulkUuid) * Number of operations that has been processed (i.e. operations with any status but 'open') */ $allProcessedOperationsQty = (int)$this->operationCollectionFactory->create() - ->addFieldToFilter('bulk_uuid', $bulkUuid) - ->getSize(); + ->addFieldToFilter('bulk_uuid', $bulkUuid) + ->getSize(); if ($allProcessedOperationsQty == 0) { return BulkSummaryInterface::NOT_STARTED; @@ -164,10 +234,12 @@ public function getBulkStatus($bulkUuid) * Number of operations that has been completed successfully */ $allCompleteOperationsQty = $this->operationCollectionFactory->create() - ->addFieldToFilter('bulk_uuid', $bulkUuid)->addFieldToFilter( - 'status', - OperationInterface::STATUS_TYPE_COMPLETE - )->getSize(); + ->addFieldToFilter('bulk_uuid', $bulkUuid) + ->addFieldToFilter( + 'status', + OperationInterface::STATUS_TYPE_COMPLETE + ) + ->getSize(); if ($allCompleteOperationsQty == $allOperationsQty) { return BulkSummaryInterface::FINISHED_SUCCESSFULLY; @@ -193,8 +265,43 @@ private function getOperationCount($bulkUuid) return (int)$connection->fetchOne( $connection->select() - ->from($metadata->getEntityTable(), 'operation_count') - ->where('uuid = ?', $bulkUuid) + ->from($metadata->getEntityTable(), 'operation_count') + ->where('uuid = ?', $bulkUuid) ); } + + /** + * @inheritDoc + */ + public function getBulkDetails($bulkUuid) + { + $bulkSummary = $this->bulkSummaryFactory->create(); + + /** @var \Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface $bulk */ + $bulk = $this->entityManager->load($bulkSummary, $bulkUuid); + + if ($bulk->getBulkId() === null) { + throw new \Magento\Framework\Exception\NoSuchEntityException( + __( + 'Bulk uuid %bulkUuid not exist', + ['bulkUuid' => $bulkUuid] + ) + ); + } + + $operations = $this->operationCollectionFactory->create()->addFieldToFilter('bulk_uuid', $bulkUuid)->getItems(); + $operationList = $this->shortOperationListFactory->create(['items' => $operations]); + + /** @var \Magento\AsynchronousOperations\Model\Operation\Details $operationDetails */ + $operationDetails = $this->operationDetailsFactory->create(['bulkUuid' => $bulkUuid]); + + /** @var \Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterface $bulkExtensionAttribute */ + $bulkExtensionAttribute = $this->bulkSummaryExtensionInterfaceFactory->create(); + $bulkExtensionAttribute->setOperationsList($operationList); + + $bulkExtensionAttribute->setOperationsCount($operationDetails); + $bulk->setExtensionAttributes($bulkExtensionAttribute); + + return $bulk; + } } diff --git a/app/code/Magento/AsynchronousOperations/Model/Operation.php b/app/code/Magento/AsynchronousOperations/Model/Operation.php index dbfce3ccd8b1c..31488c5d900ed 100644 --- a/app/code/Magento/AsynchronousOperations/Model/Operation.php +++ b/app/code/Magento/AsynchronousOperations/Model/Operation.php @@ -78,6 +78,22 @@ public function setSerializedData($serializedData) return $this->setData(self::SERIALIZED_DATA, $serializedData); } + /** + * @inheritDoc + */ + public function getResultSerializedData() + { + return $this->getData(self::RESULT_SERIALIZED_DATA); + } + + /** + * @inheritDoc + */ + public function setResultSerializedData($resultSerializedData) + { + return $this->setData(self::RESULT_SERIALIZED_DATA, $resultSerializedData); + } + /** * @inheritDoc */ diff --git a/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php b/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php index 398934f093350..2faa4e32abf95 100644 --- a/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php +++ b/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php @@ -3,11 +3,13 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\AsynchronousOperations\Model\Operation; +use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface; use Magento\Framework\Bulk\OperationInterface; -class Details +class Details implements OperationDetailsInterface { /** * @var array @@ -19,23 +21,33 @@ class Details */ private $bulkStatus; + /** + * @var null + */ + private $bulkUuid; + /** * Map between status codes and human readable indexes + * * @var array */ private $statusMap = [ - OperationInterface::STATUS_TYPE_COMPLETE => 'operations_successful', - OperationInterface::STATUS_TYPE_RETRIABLY_FAILED => 'failed_retriable', + OperationInterface::STATUS_TYPE_COMPLETE => 'operations_successful', + OperationInterface::STATUS_TYPE_RETRIABLY_FAILED => 'failed_retriable', OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED => 'failed_not_retriable', + OperationInterface::STATUS_TYPE_OPEN => 'open', + OperationInterface::STATUS_TYPE_REJECTED => 'rejected', ]; /** * @param \Magento\Framework\Bulk\BulkStatusInterface $bulkStatus */ public function __construct( - \Magento\Framework\Bulk\BulkStatusInterface $bulkStatus + \Magento\Framework\Bulk\BulkStatusInterface $bulkStatus, + $bulkUuid = null ) { $this->bulkStatus = $bulkStatus; + $this->bulkUuid = $bulkUuid; } /** @@ -47,11 +59,12 @@ public function __construct( public function getDetails($bulkUuid) { $details = [ - 'operations_total' => 0, + 'operations_total' => 0, 'operations_successful' => 0, - 'operations_failed' => 0, - 'failed_retriable' => 0, - 'failed_not_retriable' => 0, + 'operations_failed' => 0, + 'failed_retriable' => 0, + 'failed_not_retriable' => 0, + 'rejected' => 0, ]; if (array_key_exists($bulkUuid, $this->operationCache)) { @@ -65,13 +78,87 @@ public function getDetails($bulkUuid) ); } - // total is sum of successful, retriable, not retriable and open operations - $details['operations_total'] = array_sum($details) + $this->bulkStatus->getOperationsCountByBulkIdAndStatus( - $bulkUuid, - OperationInterface::STATUS_TYPE_OPEN - ); + // total is sum of successful, rejected, retriable, not retriable and open operations + $details['operations_total'] = + array_sum($details) + $this->bulkStatus->getOperationsCountByBulkIdAndStatus( + $bulkUuid, + OperationInterface::STATUS_TYPE_OPEN + ); $details['operations_failed'] = $details['failed_retriable'] + $details['failed_not_retriable']; $this->operationCache[$bulkUuid] = $details; + return $details; } + + /** + * @inheritDoc + */ + public function getOperationsTotal() + { + $this->getDetails($this->bulkUuid); + return $this->operationCache[$this->bulkUuid]['operations_total']; + } + + /** + * @inheritDoc + */ + public function getOpen() + { + $this->getDetails($this->bulkUuid); + $statusKey = $this->statusMap[OperationInterface::STATUS_TYPE_OPEN]; + + return $this->operationCache[$this->bulkUuid][$statusKey]; + } + + /** + * @inheritDoc + */ + public function getOperationsSuccessful() + { + $this->getDetails($this->bulkUuid); + $statusKey = $this->statusMap[OperationInterface::STATUS_TYPE_COMPLETE]; + + return $this->operationCache[$this->bulkUuid][$statusKey]; + } + + /** + * @inheritDoc + */ + public function getTotalFailed() + { + $this->getDetails($this->bulkUuid); + return $this->operationCache[$this->bulkUuid]['operations_failed']; + } + + /** + * @inheritDoc + */ + public function getFailedNotRetriable() + { + $statusKey = $this->statusMap[OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED]; + + return $this->operationCache[$this->bulkUuid][$statusKey]; + } + + /** + * @inheritDoc + */ + public function getFailedRetriable() + { + $this->getDetails($this->bulkUuid); + $statusKey = $this->statusMap[OperationInterface::STATUS_TYPE_RETRIABLY_FAILED]; + + return $this->operationCache[$this->bulkUuid][$statusKey]; + } + + /** + * @inheritDoc + */ + public function getRejected() + { + $this->getDetails($this->bulkUuid); + $statusKey = $this->statusMap[OperationInterface::STATUS_TYPE_REJECTED]; + + return $this->operationCache[$this->bulkUuid][$statusKey]; + } } diff --git a/app/code/Magento/AsynchronousOperations/Model/OperationShortDetails.php b/app/code/Magento/AsynchronousOperations/Model/OperationShortDetails.php new file mode 100644 index 0000000000000..818a72bc4920b --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Model/OperationShortDetails.php @@ -0,0 +1,65 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\AsynchronousOperations\Model; + +use Magento\AsynchronousOperations\Api\Data\OperationInterface; +use Magento\AsynchronousOperations\Api\Data\OperationShortDetailsInterface; +use Magento\Framework\DataObject; +use Magento\Framework\Api\ExtensibleDataInterface; + +/** + * Class OperationShortDetails + */ +class OperationShortDetails extends DataObject implements OperationShortDetailsInterface, ExtensibleDataInterface +{ + /** + * @inheritDoc + */ + public function getId() + { + return $this->getData(OperationInterface::ID); + } + + /** + * @inheritDoc + */ + public function getTopicName() + { + return $this->getData(OperationInterface::TOPIC_NAME); + } + + /** + * @inheritDoc + */ + public function getResultSerializedData() + { + return $this->getData(OperationInterface::RESULT_SERIALIZED_DATA); + } + + /** + * @inheritDoc + */ + public function getStatus() + { + return $this->getData(OperationInterface::STATUS); + } + + /** + * @inheritDoc + */ + public function getResultMessage() + { + return $this->getData(OperationInterface::RESULT_MESSAGE); + } + + /** + * @inheritDoc + */ + public function getErrorCode() + { + return $this->getData(OperationInterface::ERROR_CODE); + } +} diff --git a/app/code/Magento/AsynchronousOperations/Model/ShortOperationList.php b/app/code/Magento/AsynchronousOperations/Model/ShortOperationList.php new file mode 100644 index 0000000000000..7db033b92a068 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Model/ShortOperationList.php @@ -0,0 +1,34 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Model; + +/** + * List of bulk operations with short operation details and counter of operations. + */ +class ShortOperationList implements \Magento\AsynchronousOperations\Api\Data\ShortOperationListInterface +{ + /** + * @var array + */ + private $items; + + /** + * @param array $items [optional] + */ + public function __construct(array $items = []) + { + $this->items = $items; + } + + /** + * @inheritdoc + */ + public function getItems() + { + return $this->items; + } +} diff --git a/app/code/Magento/AsynchronousOperations/Model/StatusMapper.php b/app/code/Magento/AsynchronousOperations/Model/StatusMapper.php index 3ad260cf26a8a..e5aee6d2f59fa 100644 --- a/app/code/Magento/AsynchronousOperations/Model/StatusMapper.php +++ b/app/code/Magento/AsynchronousOperations/Model/StatusMapper.php @@ -25,6 +25,7 @@ public function operationStatusToBulkSummaryStatus($operationStatus) $statusMapping = [ OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED => BulkSummaryInterface::FINISHED_WITH_FAILURE, OperationInterface::STATUS_TYPE_RETRIABLY_FAILED => BulkSummaryInterface::FINISHED_WITH_FAILURE, + OperationInterface::STATUS_TYPE_REJECTED => BulkSummaryInterface::FINISHED_WITH_FAILURE, OperationInterface::STATUS_TYPE_COMPLETE => BulkSummaryInterface::FINISHED_SUCCESSFULLY, OperationInterface::STATUS_TYPE_OPEN => BulkSummaryInterface::IN_PROGRESS, BulkSummaryInterface::NOT_STARTED => BulkSummaryInterface::NOT_STARTED @@ -47,7 +48,8 @@ public function bulkSummaryStatusToOperationStatus($bulkStatus) $statusMapping = [ BulkSummaryInterface::FINISHED_WITH_FAILURE => [ OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED, - OperationInterface::STATUS_TYPE_RETRIABLY_FAILED + OperationInterface::STATUS_TYPE_RETRIABLY_FAILED, + OperationInterface::STATUS_TYPE_REJECTED ], BulkSummaryInterface::FINISHED_SUCCESSFULLY => OperationInterface::STATUS_TYPE_COMPLETE, BulkSummaryInterface::IN_PROGRESS => OperationInterface::STATUS_TYPE_OPEN, diff --git a/app/code/Magento/AsynchronousOperations/Setup/UpgradeSchema.php b/app/code/Magento/AsynchronousOperations/Setup/UpgradeSchema.php new file mode 100755 index 0000000000000..21286538e70b2 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Setup/UpgradeSchema.php @@ -0,0 +1,58 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Setup; + +use Magento\Framework\Setup\ModuleContextInterface; +use Magento\Framework\Setup\SchemaSetupInterface; +use Magento\Framework\Setup\UpgradeSchemaInterface; +use Magento\Framework\DB\Ddl\Table; + +/** + * Upgrade the AsynchronousOperations module DB scheme + */ +class UpgradeSchema implements UpgradeSchemaInterface +{ + /** + * {@inheritdoc} + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context) + { + $setup->startSetup(); + if (version_compare($context->getVersion(), '2.0.1', '<')) { + $this->addResultSerializedDataColumn($setup); + } + + $setup->endSetup(); + } + + /** + * Add the column 'result_serialized_data' to the Bulk Operation table. + * + * @param SchemaSetupInterface $setup + * @return void + */ + private function addResultSerializedDataColumn(SchemaSetupInterface $setup) + { + $connection = $setup->getConnection(); + $tableName = $setup->getTable('magento_operation'); + if (!$connection->tableColumnExists($tableName, 'result_serialized_data')) { + $connection->addColumn( + $tableName, + 'result_serialized_data', + [ + 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_BLOB, + 'size' => 0, + 'nullable' => true, + 'comment' => 'Result data (serialized) after perform an operation', + ] + ); + } + } +} diff --git a/app/code/Magento/AsynchronousOperations/etc/di.xml b/app/code/Magento/AsynchronousOperations/etc/di.xml index 3a4225347eeb3..a76f493f23e59 100644 --- a/app/code/Magento/AsynchronousOperations/etc/di.xml +++ b/app/code/Magento/AsynchronousOperations/etc/di.xml @@ -12,6 +12,9 @@ <preference for="Magento\Framework\Bulk\BulkManagementInterface" type="Magento\AsynchronousOperations\Model\BulkManagement" /> <preference for="Magento\Framework\Bulk\BulkStatusInterface" type="Magento\AsynchronousOperations\Model\BulkStatus" /> <preference for="Magento\Framework\Bulk\OperationManagementInterface" type="Magento\AsynchronousOperations\Model\OperationManagement" /> + <preference for="Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface" type="Magento\AsynchronousOperations\Model\Operation\Details" /> + <preference for="Magento\AsynchronousOperations\Api\Data\OperationShortDetailsInterface" type="Magento\AsynchronousOperations\Model\OperationShortDetails" /> + <preference for="Magento\AsynchronousOperations\Api\Data\ShortOperationListInterface" type="Magento\AsynchronousOperations\Model\ShortOperationList" /> <type name="Magento\Framework\EntityManager\MetadataPool"> <arguments> <argument name="metadata" xsi:type="array"> @@ -76,4 +79,6 @@ </type> <virtualType name="Magento\AsynchronousOperations\Ui\Component\DataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider"/> + + <preference for="Magento\AsynchronousOperations\Api\BulkRepositoryInterface" type="Magento\Framework\Bulk\BulkStatusInterface" /> </config> diff --git a/app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml b/app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml new file mode 100644 index 0000000000000..7179012d440d9 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd"> + <extension_attributes for="Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface"> + <attribute code="operations_list" type="Magento\AsynchronousOperations\Api\Data\ShortOperationListInterface" /> + </extension_attributes> + <extension_attributes for="Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface"> + <attribute code="operations_count" type="Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface" /> + </extension_attributes> +</config> diff --git a/app/code/Magento/AsynchronousOperations/etc/webapi.xml b/app/code/Magento/AsynchronousOperations/etc/webapi.xml new file mode 100644 index 0000000000000..6317387ee953d --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/etc/webapi.xml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd"> + + <route url="/V1/bulk/status/:bulkUuid" method="GET"> + <service class="Magento\AsynchronousOperations\Api\BulkRepositoryInterface" method="getBulkDetails"/> + <resources> + <resource ref="Magento_Logging::system_magento_logging_bulk_operations" /> + </resources> + </route> + +</routes> diff --git a/lib/internal/Magento/Framework/Bulk/OperationInterface.php b/lib/internal/Magento/Framework/Bulk/OperationInterface.php index c6d714b0363bd..4b626ac659626 100644 --- a/lib/internal/Magento/Framework/Bulk/OperationInterface.php +++ b/lib/internal/Magento/Framework/Bulk/OperationInterface.php @@ -19,6 +19,7 @@ interface OperationInterface const BULK_ID = 'bulk_uuid'; const TOPIC_NAME = 'topic_name'; const SERIALIZED_DATA = 'serialized_data'; + const RESULT_SERIALIZED_DATA = 'result_serialized_data'; const STATUS = 'status'; const RESULT_MESSAGE = 'result_message'; const ERROR_CODE = 'error_code'; @@ -31,6 +32,7 @@ interface OperationInterface const STATUS_TYPE_RETRIABLY_FAILED = 2; const STATUS_TYPE_NOT_RETRIABLY_FAILED = 3; const STATUS_TYPE_OPEN = 4; + const STATUS_TYPE_REJECTED = 5; /**#@-*/ /** @@ -101,6 +103,23 @@ public function getSerializedData(); */ public function setSerializedData($serializedData); + /** + * Result serialized Data + * + * @return string + * @since 100.3.0 + */ + public function getResultSerializedData(); + + /** + * Set result serialized data + * + * @param string $resultSerializedData + * @return $this + * @since 100.3.0 + */ + public function setResultSerializedData($resultSerializedData); + /** * Get operation status * From ecab41dc11518ffbaced7e978b22326a16d9d454 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Tue, 20 Mar 2018 12:28:27 +0200 Subject: [PATCH 113/668] MAGETWO-86939: Support Category Type --- .../Model/ResourceModel/CategoryProduct.php | 43 +++++++ .../Resolver/Categories/Query/Filter.php | 71 +++++++++++ .../Resolver/Categories/Query/Search.php | 52 ++++++++ .../Model/Resolver/CategoryTree.php | 111 ++++++++++++++++++ .../Products/DataProvider/Product.php | 49 +++++++- .../Magento/CatalogGraphQl/etc/graphql.xml | 17 +++ .../Output/ElementMapper/Formatter/Fields.php | 9 +- 7 files changed, 345 insertions(+), 7 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Filter.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Search.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php diff --git a/app/code/Magento/Catalog/Model/ResourceModel/CategoryProduct.php b/app/code/Magento/Catalog/Model/ResourceModel/CategoryProduct.php index 5fbc2ddf94bb5..9ff29faba8c05 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/CategoryProduct.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/CategoryProduct.php @@ -29,4 +29,47 @@ protected function _construct() { $this->_init('catalog_category_product', 'entity_id'); } + + /** + * Retrieve distinct product ids, that are linked to categories + * + * @return array + */ + public function getDistinctProductIds() + { + $productIdsSelect = $this + ->getConnection() + ->select() + ->from($this->getTable('catalog_category_product'), 'product_id') + ->distinct('product_id'); + + return $this->getConnection()->fetchAll($productIdsSelect); + } + + /** + * Retrieve product ids grouped by categories + * + * @return array + */ + public function getProductsIdsGroupedByCategories() + { + $productIdsGroupedByCategories = []; + $productIdsSelect = $this + ->getConnection() + ->select() + ->from( + $this->getTable('catalog_category_product'), + ['category_id', 'product_id', 'position'] + ); + + $categoriesData = $this->getConnection()->fetchAll($productIdsSelect); + + foreach ($categoriesData as $categoryData) { + $categoryId = $categoryData['category_id']; + $productId = $categoryData['product_id']; + $productIdsGroupedByCategories[$categoryId][$productId] = $categoryData['position']; + } + + return $productIdsGroupedByCategories; + } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Filter.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Filter.php new file mode 100644 index 0000000000000..dcc87b733d9c4 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Filter.php @@ -0,0 +1,71 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogGraphQl\Model\Resolver\Categories\Query; + +use Magento\Catalog\Api\CategoryManagementInterface; +use Magento\Catalog\Api\Data\CategoryTreeInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; + +/** + * Retrieve filtered categories data based off given search criteria in a format that GraphQL can interpret. + */ +class Filter +{ + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + + /** + * @var FormatterInterface + */ + private $formatter; + + /** + * @var CategoryManagementInterface + */ + private $categoryManagement; + + /** + * @var \Magento\Framework\Reflection\DataObjectProcessor + */ + private $dataObjectProcessor; + + /** + * @param CategoryManagementInterface $categoryManagement + * @param SearchCriteriaBuilder $searchCriteriaBuilder + * @param \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor + * @param FormatterInterface $formatter + */ + public function __construct( + CategoryManagementInterface $categoryManagement, + SearchCriteriaBuilder $searchCriteriaBuilder, + \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor, + FormatterInterface $formatter + ) { + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->formatter = $formatter; + $this->categoryManagement = $categoryManagement; + $this->dataObjectProcessor = $dataObjectProcessor; + } + + /** + * Filter catalog product data based off given search criteria + * + * @param SearchCriteriaInterface $searchCriteria + * @return array + */ + public function getResult(SearchCriteriaInterface $searchCriteria) : array + { + $categoriesTree = $this->categoryManagement->getTree(2); + $categoriesTreeOutput = $this->dataObjectProcessor + ->buildOutputDataArray($categoriesTree, CategoryTreeInterface::class); + return $categoriesTreeOutput; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Search.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Search.php new file mode 100644 index 0000000000000..660071d9c4a42 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Search.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogGraphQl\Model\Resolver\Categories\Query; + +use Magento\Framework\Api\Search\SearchCriteriaInterface; +use Magento\CatalogGraphQl\Model\Resolver\Categories\SearchResult; +use Magento\CatalogGraphQl\Model\Resolver\Categories\SearchResultFactory; +use Magento\Search\Api\SearchInterface; + +/** + * Full text search for catalog using given search criteria. + */ +class Search +{ + /** + * @var SearchInterface + */ + private $search; + + /** + * @param SearchInterface $search + */ + public function __construct( + SearchInterface $search + ) { + $this->search = $search; + } + + /** + * Return results of full text catalog search of given term, and will return filtered results if filter is specified + * + * @param SearchCriteriaInterface $searchCriteria + * @return SearchResult + */ + public function getResult(SearchCriteriaInterface $searchCriteria) + { + $realPageSize = $searchCriteria->getPageSize(); + $realCurrentPage = $searchCriteria->getCurrentPage(); + // Current page must be set to 0 and page size to max for search to grab all ID's as temporary workaround + // for MAGETWO-85611 + $searchCriteria->setPageSize(PHP_INT_MAX); + $searchCriteria->setCurrentPage(0); + $searchResult = $this->search->search($searchCriteria); + $searchCriteria->setPageSize($realPageSize); + $searchCriteria->setCurrentPage($realCurrentPage); + return $this->searchResultFactory->create($searchResult->getTotalCount(), $searchResult->getItems()); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php new file mode 100644 index 0000000000000..be5fd746bb7bf --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php @@ -0,0 +1,111 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogGraphQl\Model\Resolver; + +use GraphQL\Deferred; +use GraphQL\Type\Definition\ResolveInfo; +use Magento\CatalogGraphQl\Model\Resolver\Categories\Query\Filter; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Promise; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Argument\SearchCriteria\Builder; +use Magento\CatalogGraphQl\Model\Resolver\Categories\Query\Search; + +/** + * Products field resolver, used for GraphQL request processing. + */ +class CategoryTree implements ResolverInterface +{ + /** + * Category Tree key in graphql + */ + const CATEGORY_TREE_KEY = 'children'; + + /** + * @var Builder + */ + private $searchCriteriaBuilder; + + /** + * @var Search + */ + private $categoriesSearch; + + /** + * @var Filter + */ + private $categoriesFilter; + + /** + * @var Products\DataProvider\Product + */ + private $productDataProvider; + + /** + * CategoryTree constructor. + * @param Builder $searchCriteriaBuilder + * @param Search $categoriesSearch + * @param Filter $categoriesFilter + * @param Products\DataProvider\Product $productDataProvider + */ + public function __construct( + Builder $searchCriteriaBuilder, + Search $categoriesSearch, + Filter $categoriesFilter, + Products\DataProvider\Product $productDataProvider + ) { + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->categoriesSearch = $categoriesSearch; + $this->categoriesFilter = $categoriesFilter; + $this->productDataProvider = $productDataProvider; + } + + /** + * @param Field $field + * @param array|null $value + * @param array|null $args + * @param $context + * @param ResolveInfo $info + * @return mixed + */ + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) + { + if (isset($value[$field->getName()])) { + return $value[$field->getName()]; + } + + $searchCriteria = $this->searchCriteriaBuilder->build($args); + + if (isset($args['search'])) { + $categoriesTree = $this->categoriesSearch->getResult($searchCriteria); + } else { + $categoriesTree = $this->categoriesFilter->getResult($searchCriteria); + } + + $processedCategoryTree = $this->processCategoriesTree([$categoriesTree]); + return ['category_tree' => $processedCategoryTree]; + } + + /** + * @param array $categoriesTree + * @return array + */ + private function processCategoriesTree(array $categoriesTree) + { + foreach ($categoriesTree as $nodeKey => $node) { + if (isset($node['children_data'])) { + $categoriesTree[$nodeKey][self::CATEGORY_TREE_KEY] = $this->processCategoriesTree($node['children_data']); + unset($categoriesTree[$nodeKey]['children_data']); + } + + $categoryProducts = $this->productDataProvider->getListOfProductsInCategories($node['id']); + $categoriesTree[$nodeKey]['products']['items'] = $categoryProducts; + } + + return $categoriesTree; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php index b79d3c926dcdd..8bf3cd26888de 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php @@ -6,6 +6,8 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider; +use Magento\Catalog\Model\ResourceModel\CategoryProduct; +use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\Data\SearchResultInterface; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; @@ -23,6 +25,11 @@ class Product */ private $collectionFactory; + /** + * @var array + */ + private $productsByCategories = null; + /** * @var JoinProcessorInterface */ @@ -38,22 +45,38 @@ class Product */ private $searchResultsFactory; + /** + * @var CategoryProduct + */ + private $categoryProduct; + + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + /** * @param CollectionFactory $collectionFactory * @param JoinProcessorInterface $joinProcessor * @param CollectionProcessorInterface $collectionProcessor * @param ProductSearchResultsInterfaceFactory $searchResultsFactory + * @param CategoryProduct $categoryProduct + * @param SearchCriteriaBuilder $searchCriteriaBuilder */ public function __construct( CollectionFactory $collectionFactory, JoinProcessorInterface $joinProcessor, CollectionProcessorInterface $collectionProcessor, - ProductSearchResultsInterfaceFactory $searchResultsFactory + ProductSearchResultsInterfaceFactory $searchResultsFactory, + CategoryProduct $categoryProduct, + SearchCriteriaBuilder $searchCriteriaBuilder ) { $this->collectionFactory = $collectionFactory; $this->joinProcessor = $joinProcessor; $this->collectionProcessor = $collectionProcessor; $this->searchResultsFactory = $searchResultsFactory; + $this->categoryProduct = $categoryProduct; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; } /** @@ -86,4 +109,28 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr $searchResult->setTotalCount($collection->getSize()); return $searchResult; } + + /** + * Retrieve products list by category ids + * + * @param $categoryId + * @return array + */ + public function getListOfProductsInCategories($categoryId) + { + if ($this->productsByCategories === null) { + $searchCriteria = $this->searchCriteriaBuilder->addFilter( + 'entity_id', + $this->categoryProduct->getDistinctProductIds(), + 'in' + ) + ->create(); + + $this->productsByCategories = $this->getList($searchCriteria)->getItems(); + } + + $productsByCategories = $this->categoryProduct->getProductsIdsGroupedByCategories(); + $productIds = $productsByCategories[$categoryId] ?? []; + return array_intersect_key($this->productsByCategories, array_keys($productIds)); + } } diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql.xml b/app/code/Magento/CatalogGraphQl/etc/graphql.xml index 69957566a092c..ee1c05b8a4089 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql.xml @@ -12,6 +12,7 @@ <argument xsi:type="ScalarArgument" name="currentPage" type="Int" default="0" description="Specifies which page of results to return. If no value is specified, the first page is returned. If you specify a value that is greater than the number of available pages, an error is returned."/> <argument xsi:type="ObjectArgument" name="sort" type="ProductSortInput" description="Specifies which field or fields to use for sorting the results. If you specify more than one field, Magento sorts by the first field listed. Then, if any items have the same value, those items will be sorted by the secondary field. The value for each field can be set to either ASC (ascending) or DESC (descending)."/> </field> + <field xsi:type="ObjectOutputField" name="categories" type="Categories" resolver="Magento\CatalogGraphQl\Model\Resolver\CategoryTree" /> </type> <type xsi:type="Enum" name="CurrencyEnum"> <item name="afn">AFN</item> @@ -272,6 +273,18 @@ <field xsi:type="ObjectOutputField" name="price" type="ProductPrices" description="The price of the item, including the value and the currency code."/> <field xsi:type="ScalarOutputField" name="gift_message_available" type="String" description="Indicates whether a gift message is available."/> </type> + <type xsi:type="OutputType" name="CategoryTree"> + <field xsi:type="ScalarOutputField" name="id" type="Int" description="Category Identifier" /> + <field xsi:type="ScalarOutputField" name="is_active" type="Boolean" description="Is Active?" /> + <field xsi:type="ScalarOutputField" name="position" type="Int" description="Category Position" /> + <field xsi:type="ScalarOutputField" name="level" type="Int" description="Category Level" /> + <field xsi:type="ScalarOutputField" name="created_at" type="String" description="Category Level" /> + <field xsi:type="ScalarOutputField" name="updated_at" type="String" description="Category Level" /> + <field xsi:type="ScalarOutputField" name="path" type="String" description="Category Path" /> + <field xsi:type="ScalarOutputField" name="product_count" type="Int" description="Count of products in category" /> + <field xsi:type="ObjectOutputField" name="products" type="Products" description="Products assigned to category" /> + <field xsi:type="ObjectArrayOutputField" name="children" itemType="CategoryTree" resolver="Magento\CatalogGraphQl\Model\Resolver\CategoryTree" description="Children categories represented as a tree" /> + </type> <type xsi:type="OutputInterface" name="PhysicalProductInterface" typeResolver="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> <field xsi:type="ScalarOutputField" name="weight" type="Float" description="The weight of a physical product"/> </type> @@ -378,6 +391,10 @@ <field xsi:type="ObjectOutputField" name="page_info" type="SearchResultPageInfo" description="An object that includes the `page_info` and `currentPage` values specified in the query"/> <field xsi:type="ScalarOutputField" name="total_count" type="Int" description="The number of products returned."/> </type> + <type xsi:type="OutputType" name="Categories"> + <field xsi:type="ObjectArrayOutputField" name="category_tree" itemType="CategoryTree" description="Tree of categories."/> + <field xsi:type="ScalarOutputField" name="total_count" type="Int" description="The number of categories returned."/> + </type> <type xsi:type="OutputType" name="MediaGalleryEntry"> <field xsi:type="ScalarOutputField" name="id" type="Int" description="The identifier assigned to the object"/> <field xsi:type="ScalarOutputField" name="media_type" type="String" description=" 'image' or 'video'"/> diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php index d372b79d452d3..7349cb95d7e27 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php @@ -109,13 +109,9 @@ public function format(TypeInterface $typeStructure, OutputType $outputType) : a } else { if ($typeStructure->getName() == $field->getTypeName()) { $type = $outputType; + $type = $this->wrappedTypeProcessor->processWrappedType($field, $type); } else { - if ($typeStructure->getName() == $field->getTypeName()) { - $type = $outputType; - } else { - $type = $this->outputMapper->getTypeObject($field->getTypeName()); - } - + $type = $this->outputMapper->getTypeObject($field->getTypeName()); $type = $this->wrappedTypeProcessor->processWrappedType($field, $type); } } @@ -139,6 +135,7 @@ function ($value, $args, $context, $info) use ($resolver, $field) { } $config = $this->formatArguments($field, $config); } + return $config; } From a4b07e9b0000536e5b6e90bc3640f10304929c21 Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" <a.vasiliev@sam-solutions.biz> Date: Tue, 20 Mar 2018 12:57:53 +0200 Subject: [PATCH 114/668] Asynchronous WebAPI implementation --- .../AsyncResponse/ItemStatusInterface.php | 112 +++++ .../Data/AsyncResponse/ItemsListInterface.php | 26 + .../Api/Data/AsyncResponseInterface.php | 73 +++ .../RemoteServiceReader/Communication.php | 83 ++++ .../Config/RemoteServiceReader/Consumer.php | 69 +++ .../Config/RemoteServiceReader/Publisher.php | 66 +++ .../Config/RemoteServiceReader/Topology.php | 84 ++++ .../Rest/Async/InputParamsResolver.php | 137 +++++ .../Rest/AsynchronousRequestProcessor.php | 125 +++++ .../AsynchronousSchemaRequestProcessor.php | 71 +++ app/code/Magento/WebapiAsync/LICENSE.txt | 48 ++ app/code/Magento/WebapiAsync/LICENSE_AFL.txt | 48 ++ .../WebapiAsync/Model/AsyncResponse.php | 63 +++ .../Model/AsyncResponse/ItemStatus.php | 101 ++++ .../Model/AsyncResponse/ItemsList.php | 33 ++ app/code/Magento/WebapiAsync/Model/Config.php | 155 ++++++ .../WebapiAsync/Model/ConfigInterface.php | 64 +++ .../Model/MessageQueue/MassConsumer.php | 263 ++++++++++ .../Model/MessageQueue/MassPublisher.php | 104 ++++ .../Model/MessageQueue/MassSchedule.php | 230 +++++++++ app/code/Magento/WebapiAsync/README.md | 3 + .../Test/ApiFunctional/BulkScheduleTest.php | 466 ++++++++++++++++++ .../Unit/Controller/PathProcessorTest.php | 66 +++ .../Test/Unit/Controller/RestTest.php | 320 ++++++++++++ app/code/Magento/WebapiAsync/composer.json | 35 ++ app/code/Magento/WebapiAsync/etc/di.xml | 47 ++ app/code/Magento/WebapiAsync/etc/module.xml | 16 + .../WebapiAsync/etc/queue_consumer.xml | 16 + .../WebapiAsync/etc/queue_topology.xml | 13 + .../WebapiAsync/etc/webapi_rest/di.xml | 20 + app/code/Magento/WebapiAsync/registration.php | 11 + app/etc/di.xml | 7 + .../Framework/MessageQueue/MergerFactory.php | 50 +- 33 files changed, 3022 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemStatusInterface.php create mode 100644 app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemsListInterface.php create mode 100644 app/code/Magento/WebapiAsync/Api/Data/AsyncResponseInterface.php create mode 100644 app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php create mode 100644 app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php create mode 100644 app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php create mode 100644 app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php create mode 100644 app/code/Magento/WebapiAsync/Controller/Rest/Async/InputParamsResolver.php create mode 100644 app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php create mode 100644 app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessor.php create mode 100644 app/code/Magento/WebapiAsync/LICENSE.txt create mode 100644 app/code/Magento/WebapiAsync/LICENSE_AFL.txt create mode 100644 app/code/Magento/WebapiAsync/Model/AsyncResponse.php create mode 100644 app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemStatus.php create mode 100644 app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemsList.php create mode 100644 app/code/Magento/WebapiAsync/Model/Config.php create mode 100644 app/code/Magento/WebapiAsync/Model/ConfigInterface.php create mode 100644 app/code/Magento/WebapiAsync/Model/MessageQueue/MassConsumer.php create mode 100644 app/code/Magento/WebapiAsync/Model/MessageQueue/MassPublisher.php create mode 100644 app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php create mode 100644 app/code/Magento/WebapiAsync/README.md create mode 100644 app/code/Magento/WebapiAsync/Test/ApiFunctional/BulkScheduleTest.php create mode 100644 app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php create mode 100644 app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php create mode 100644 app/code/Magento/WebapiAsync/composer.json create mode 100755 app/code/Magento/WebapiAsync/etc/di.xml create mode 100644 app/code/Magento/WebapiAsync/etc/module.xml create mode 100644 app/code/Magento/WebapiAsync/etc/queue_consumer.xml create mode 100644 app/code/Magento/WebapiAsync/etc/queue_topology.xml create mode 100644 app/code/Magento/WebapiAsync/etc/webapi_rest/di.xml create mode 100644 app/code/Magento/WebapiAsync/registration.php diff --git a/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemStatusInterface.php b/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemStatusInterface.php new file mode 100644 index 0000000000000..538f29e2f509f --- /dev/null +++ b/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemStatusInterface.php @@ -0,0 +1,112 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Api\Data\AsyncResponse; + +/** + * ItemStatusInterface interface + * Temporary object with status of requested item. + * Indicate if entity param was Accepted|Rejected to bulk schedule + * + * @api + * @since 100.3.0 + */ +interface ItemStatusInterface +{ + const ENTITY_ID = 'entity_id'; + const DATA_HASH = 'data_hash'; + const STATUS = 'status'; + const ERROR_MESSAGE = 'error_message'; + const ERROR_CODE = 'error_code'; + + const STATUS_ACCEPTED = 'accepted'; + const STATUS_REJECTED = 'rejected'; + + /** + * Get entity Id. + * + * @return int + * @since 100.3.0 + */ + public function getId(); + + /** + * Sets entity Id. + * + * @param int $entityId + * @return $this + * @since 100.3.0 + */ + public function setId($entityId); + + /** + * Get hash of entity data. + * + * @return string md5 hash of entity params array. + * @since 100.3.0 + */ + public function getDataHash(); + + /** + * Sets hash of entity data. + * + * @param string $hash md5 hash of entity params array. + * @return $this + * @since 100.3.0 + */ + public function setDataHash($hash); + + /** + * Get status. + * + * @return string accepted|rejected + * @since 100.3.0 + */ + public function getStatus(); + + /** + * Sets entity status. + * + * @param string $status accepted|rejected + * @return $this + * @since 100.3.0 + */ + public function setStatus($status = self::STATUS_ACCEPTED); + + /** + * Get error information. + * + * @return string|null + * @since 100.3.0 + */ + public function getErrorMessage(); + + /** + * Sets error information. + * + * @param string|null|\Exception $error + * @return $this + * @since 100.3.0 + */ + public function setErrorMessage($error = null); + + /** + * Get error code. + * + * @return int|null + * @since 100.3.0 + */ + public function getErrorCode(); + + /** + * Sets error information. + * + * @param int|null|\Exception $errorCode Default: null + * @return $this + * @since 100.3.0 + */ + public function setErrorCode($errorCode = null); +} diff --git a/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemsListInterface.php b/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemsListInterface.php new file mode 100644 index 0000000000000..7fe73f9b8d4f5 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemsListInterface.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Api\Data\AsyncResponse; + +/** + * AsyncResponseItemListInterface interface + * List of status requested entities to async router. Accepted|Rejected + * Temporary data list for async router response. + * + * @api + * @since 100.3.0 + */ +interface ItemsListInterface +{ + /** + * Get list of statuses for requested entities. + * + * @return \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterface[] + * @since 100.3.0 + */ + public function getItems(); +} diff --git a/app/code/Magento/WebapiAsync/Api/Data/AsyncResponseInterface.php b/app/code/Magento/WebapiAsync/Api/Data/AsyncResponseInterface.php new file mode 100644 index 0000000000000..bc9ba54ca7bf4 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Api/Data/AsyncResponseInterface.php @@ -0,0 +1,73 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Api\Data; + +/** + * Interface AsyncResponseInterface + * Temporary data object to give response from webapi async router + * + * @api + * @since 100.3.0 + */ +interface AsyncResponseInterface +{ + const BULK_UUID = 'bulk_uuid'; + const REQUEST_ITEMS = 'request_items'; + + /** + * Gets the bulk uuid. + * + * @return string Bulk Uuid. + * @since 100.3.0 + */ + public function getBulkUuid(); + + /** + * Sets the bulk uuid. + * + * @param string $bulkUuid + * @return $this + * @since 100.3.0 + */ + public function setBulkUuid($bulkUuid); + + /** + * Gets the list of request items with status data. + * + * @return \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface + * @since 100.3.0 + */ + public function getRequestItems(); + + /** + * Sets the list of request items with status data. + * + * @param \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface $requestItems + * @return $this + * @since 100.3.0 + */ + public function setRequestItems(\Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface $requestItems); + + /** + * Retrieve existing extension attributes object. + * + * @return \Magento\WebapiAsync\Api\Data\AsyncResponseExtensionInterface|null + * @since 100.3.0 + */ + public function getExtensionAttributes(); + + /** + * Set an extension attributes object. + * + * @param \Magento\WebapiAsync\Api\Data\AsyncResponseExtensionInterface $extensionAttributes + * @return $this + * @since 100.3.0 + */ + public function setExtensionAttributes( + \Magento\WebapiAsync\Api\Data\AsyncResponseExtensionInterface $extensionAttributes + ); +} diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php new file mode 100644 index 0000000000000..f2a54d8fd2388 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php @@ -0,0 +1,83 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Code\Generator\Config\RemoteServiceReader; + +use Magento\Framework\Communication\ConfigInterface as CommunicationConfig; +use Magento\WebapiAsync\Model\ConfigInterface as WebApiAsyncConfig; +use Magento\Framework\Communication\Config\ReflectionGenerator; + +/** + * Remote service reader with auto generated configuration for communication.xml + */ +class Communication implements \Magento\Framework\Config\ReaderInterface +{ + + /** + * @var \Magento\WebapiAsync\Model\ConfigInterface + */ + private $webapiAsyncConfig; + + /** + * @var \Magento\Framework\Communication\Config\ReflectionGenerator + */ + private $reflectionGenerator; + + /** + * Initialize dependencies. + * + * @param \Magento\WebapiAsync\Model\ConfigInterface $webapiAsyncConfig + * @param \Magento\Framework\Communication\Config\ReflectionGenerator $reflectionGenerator + */ + public function __construct( + WebApiAsyncConfig $webapiAsyncConfig, + ReflectionGenerator $reflectionGenerator + ) { + $this->webapiAsyncConfig = $webapiAsyncConfig; + $this->reflectionGenerator = $reflectionGenerator; + } + + /** + * Generate communication configuration based on remote services declarations + * + * @param string|null $scope + * @return array + */ + public function read($scope = null) + { + try { + $asyncServicesData = $this->webapiAsyncConfig->getServices(); + } catch (\Exception $e) { + return []; + } + $result = []; + foreach ($asyncServicesData as $serviceData) { + $topicName = $serviceData[WebApiAsyncConfig::SERVICE_PARAM_KEY_TOPIC]; + $serviceClass = $serviceData[WebApiAsyncConfig::SERVICE_PARAM_KEY_INTERFACE]; + $serviceMethod = $serviceData[WebApiAsyncConfig::SERVICE_PARAM_KEY_METHOD]; + + $topicConfig = $this->reflectionGenerator->generateTopicConfigForServiceMethod( + $topicName, + $serviceClass, + $serviceMethod, + [ + WebApiAsyncConfig::DEFAULT_HANDLER_NAME => [ + CommunicationConfig::HANDLER_TYPE => $serviceClass, + CommunicationConfig::HANDLER_METHOD => $serviceMethod, + ], + ] + ); + $rewriteTopicParams = [ + CommunicationConfig::TOPIC_IS_SYNCHRONOUS => false, + CommunicationConfig::TOPIC_RESPONSE => null, + ]; + $result[$topicName] = array_merge($topicConfig, $rewriteTopicParams); + } + $result[WebApiAsyncConfig::SYSTEM_TOPIC_NAME] = WebApiAsyncConfig::SYSTEM_TOPIC_CONFIGURATION; + + return [CommunicationConfig::TOPICS => $result]; + } +} diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php new file mode 100644 index 0000000000000..4b6c9c4c2dea7 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php @@ -0,0 +1,69 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Code\Generator\Config\RemoteServiceReader; + +use Magento\WebapiAsync\Model\ConfigInterface as WebApiAsyncConfig; + +/** + * Remote service reader with auto generated configuration for queue_consumer.xml + */ +class Consumer implements \Magento\Framework\Config\ReaderInterface +{ + /** + * @var \Magento\WebapiAsync\Model\ConfigInterface + */ + private $webapiAsyncConfig; + + /** + * Initialize dependencies. + * + * @param \Magento\WebapiAsync\Model\ConfigInterface $webapiAsyncConfig + */ + public function __construct( + WebApiAsyncConfig $webapiAsyncConfig + ) { + $this->webapiAsyncConfig = $webapiAsyncConfig; + } + + /** + * Generate consumer configuration based on remote services declarations + * + * @param string|null $scope + * @return array + */ + public function read($scope = null) + { + try { + $asyncServicesData = $this->webapiAsyncConfig->getServices(); + } catch (\Exception $e) { + return []; + } + $result = []; + foreach ($asyncServicesData as $serviceData) { + $topicName = $serviceData[WebApiAsyncConfig::SERVICE_PARAM_KEY_TOPIC]; + $serviceClass = $serviceData[WebApiAsyncConfig::SERVICE_PARAM_KEY_INTERFACE]; + $serviceMethod = $serviceData[WebApiAsyncConfig::SERVICE_PARAM_KEY_METHOD]; + + $result[$topicName] = + [ + 'name' => $topicName, + 'queue' => $topicName, + 'consumerInstance' => WebApiAsyncConfig::DEFAULT_CONSUMER_INSTANCE, + 'connection' => WebApiAsyncConfig::DEFAULT_CONSUMER_CONNECTION, + 'maxMessages' => WebApiAsyncConfig::DEFAULT_CONSUMER_MAX_MESSAGE, + 'handlers' => [ + WebApiAsyncConfig::DEFAULT_HANDLER_NAME => [ + 'type' => $serviceClass, + 'method' => $serviceMethod, + ], + ], + ]; + } + + return $result; + } +} diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php new file mode 100644 index 0000000000000..3a04c0a2e6149 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Code\Generator\Config\RemoteServiceReader; + +use Magento\WebapiAsync\Model\ConfigInterface as WebApiAsyncConfig; + +/** + * Remote service reader with auto generated configuration for queue_publisher.xml + */ +class Publisher implements \Magento\Framework\Config\ReaderInterface +{ + + /** + * @var \Magento\WebapiAsync\Model\ConfigInterface + */ + private $webapiAsyncConfig; + + /** + * Initialize dependencies. + * + * @param \Magento\WebapiAsync\Model\ConfigInterface $webapiAsyncConfig + */ + public function __construct( + WebApiAsyncConfig $webapiAsyncConfig + ) { + $this->webapiAsyncConfig = $webapiAsyncConfig; + } + + /** + * Generate publisher configuration based on remote services declarations + * + * @param string|null $scope + * @return array + */ + public function read($scope = null) + { + try { + $asyncServicesData = $this->webapiAsyncConfig->getServices(); + } catch (\Exception $e) { + return []; + } + $result = []; + foreach ($asyncServicesData as $serviceData) { + $topicName = $serviceData[WebApiAsyncConfig::SERVICE_PARAM_KEY_TOPIC]; + + $result[$topicName] = + [ + 'topic' => $topicName, + 'disabled' => false, + 'connections' => [ + 'amqp' => [ + 'name' => 'amqp', + 'exchange' => 'magento', + 'disabled' => false, + ], + ], + ]; + } + + return $result; + } +} diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php new file mode 100644 index 0000000000000..7e998cb97e215 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php @@ -0,0 +1,84 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Code\Generator\Config\RemoteServiceReader; + +use Magento\WebapiAsync\Model\ConfigInterface as WebApiAsyncConfig; +use Magento\Framework\Communication\Config\ReflectionGenerator; + +/** + * Remote service reader with auto generated configuration for queue_topology.xml + */ +class Topology implements \Magento\Framework\Config\ReaderInterface +{ + + /** + * @var \Magento\WebapiAsync\Model\ConfigInterface + */ + private $webapiAsyncConfig; + + /** + * @var \Magento\Framework\Communication\Config\ReflectionGenerator + */ + private $reflectionGenerator; + + /** + * Initialize dependencies. + * + * @param \Magento\WebapiAsync\Model\ConfigInterface $webapiAsyncConfig + */ + public function __construct( + WebApiAsyncConfig $webapiAsyncConfig, + ReflectionGenerator $reflectionGenerator + ) { + $this->webapiAsyncConfig = $webapiAsyncConfig; + $this->reflectionGenerator = $reflectionGenerator; + } + + /** + * Generate topology configuration based on remote services declarations + * + * @param string|null $scope + * @return array + */ + public function read($scope = null) + { + try { + $asyncServicesData = $this->webapiAsyncConfig->getServices(); + } catch (\Exception $e) { + return []; + } + + $bindings = []; + foreach ($asyncServicesData as $serviceData) { + $topicName = $serviceData[WebApiAsyncConfig::SERVICE_PARAM_KEY_TOPIC]; + $bindings[$topicName] = [ + 'id' => $topicName, + 'topic' => $topicName, + 'destinationType' => 'queue', + 'destination' => $topicName, + 'disabled' => false, + 'arguments' => [], + ]; + } + + $result = [ + 'magento-async--amqp' => + [ + 'name' => 'magento', + 'type' => 'topic', + 'connection' => 'amqp', + 'durable' => true, + 'autoDelete' => false, + 'arguments' => [], + 'internal' => false, + 'bindings' => $bindings, + ], + ]; + + return $result; + } +} diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/Async/InputParamsResolver.php b/app/code/Magento/WebapiAsync/Controller/Rest/Async/InputParamsResolver.php new file mode 100644 index 0000000000000..9a8232e30a147 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Controller/Rest/Async/InputParamsResolver.php @@ -0,0 +1,137 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Controller\Rest\Async; + +use Magento\Framework\Webapi\ServiceInputProcessor; +use Magento\Framework\Webapi\Rest\Request as RestRequest; +use Magento\Webapi\Controller\Rest\Router; +use Magento\Webapi\Controller\Rest\ParamsOverrider; +use Magento\Webapi\Controller\Rest\RequestValidator; +use Magento\Webapi\Controller\Rest\InputParamsResolver as WebapiInputParamsResolver; + +/** + * This class is responsible for retrieving resolved input data + */ +class InputParamsResolver +{ + /** + * @var RestRequest + */ + private $request; + + /** + * @var ParamsOverrider + */ + private $paramsOverrider; + + /** + * @var ServiceInputProcessor + */ + private $serviceInputProcessor; + + /** + * @var Router + */ + private $router; + + /** + * @var RequestValidator + */ + private $requestValidator; + + /** + * @var \Magento\Webapi\Controller\Rest\InputParamsResolver + */ + private $inputParamsResolver; + + /** + * Initialize dependencies. + * + * @param \Magento\Framework\Webapi\Rest\Request $request + * @param \Magento\Webapi\Controller\Rest\ParamsOverrider $paramsOverrider + * @param \Magento\Framework\Webapi\ServiceInputProcessor $inputProcessor + * @param \Magento\Webapi\Controller\Rest\Router $router + * @param \Magento\Webapi\Controller\Rest\RequestValidator $requestValidator + * @param \Magento\Webapi\Controller\Rest\InputParamsResolver $inputParamsResolver + */ + public function __construct( + RestRequest $request, + ParamsOverrider $paramsOverrider, + ServiceInputProcessor $inputProcessor, + Router $router, + RequestValidator $requestValidator, + WebapiInputParamsResolver $inputParamsResolver + ) { + $this->request = $request; + $this->paramsOverrider = $paramsOverrider; + $this->serviceInputProcessor = $inputProcessor; + $this->router = $router; + $this->requestValidator = $requestValidator; + $this->inputParamsResolver = $inputParamsResolver; + } + + /** + * Process and resolve input parameters + * Return array with validated input params + * or \Exception object for failed validation params + * + * @return array + * @throws \Magento\Framework\Webapi\Exception + */ + public function resolve() + { + $this->requestValidator->validate(); + $webapiResolvedParams = []; + $inputData = $this->request->getRequestData(); + + //simple check if async request have single or bulk entities + if (array_key_exists(0, $inputData)) { + foreach ($inputData as $key => $singleParams) { + $webapiResolvedParams[$key] = $this->resolveParams($singleParams); + } + } else {//single item request + $webapiResolvedParams[] = $this->resolveParams($inputData); + } + + return $webapiResolvedParams; + } + + /** + * @return \Magento\Webapi\Controller\Rest\Router\Route + */ + public function getRoute() + { + return $this->inputParamsResolver->getRoute(); + } + + /** + * @return array|\Exception + */ + private function resolveParams($inputData) + { + $route = $this->getRoute(); + $serviceMethodName = $route->getServiceMethod(); + $serviceClassName = $route->getServiceClass(); + + /* + * Valid only for updates using PUT when passing id value both in URL and body + */ + if ($this->request->getHttpMethod() == RestRequest::HTTP_METHOD_PUT) { + $inputData = $this->paramsOverrider->overrideRequestBodyIdWithPathParam( + $this->request->getParams(), + $inputData, + $serviceClassName, + $serviceMethodName + ); + $inputData = array_merge($inputData, $this->request->getParams()); + } + + $inputData = $this->paramsOverrider->override($inputData, $route->getParameters()); + $inputParams = $this->serviceInputProcessor->process($serviceClassName, $serviceMethodName, $inputData); + return $inputParams; + } +} diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php new file mode 100644 index 0000000000000..ff39ea3f3ed55 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php @@ -0,0 +1,125 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Controller\Rest; + +use Magento\Webapi\Controller\Rest\RequestProcessorInterface; +use Magento\Framework\Webapi\Rest\Response as RestResponse; +use Magento\WebapiAsync\Controller\Rest\Async\InputParamsResolver; +use Magento\WebapiAsync\Model\MessageQueue\MassSchedule; +use Magento\WebapiAsync\Model\ConfigInterface as WebApiAsyncConfig; +use Magento\Webapi\Controller\Rest\SynchronousRequestProcessor; +use Magento\Framework\Reflection\DataObjectProcessor; + +class AsynchronousRequestProcessor implements RequestProcessorInterface +{ + const PROCESSOR_PATH = 'async/V1'; + + /** + * @var \Magento\Framework\Webapi\Rest\Response + */ + private $response; + + /** + * @var \Magento\WebapiAsync\Controller\Rest\Async\InputParamsResolver + */ + private $inputParamsResolver; + + /** + * @var \Magento\WebapiAsync\Model\MessageQueue\MassSchedule + */ + private $asyncBulkPublisher; + + /** + * @var \Magento\WebapiAsync\Model\ConfigInterface + */ + private $webapiAsyncConfig; + + /** + * @var \Magento\Framework\Reflection\DataObjectProcessor + */ + private $dataObjectProcessor; + + /** + * Initialize dependencies. + * + * @param \Magento\Framework\Webapi\Rest\Response $response + * @param \Magento\WebapiAsync\Controller\Rest\Async\InputParamsResolver $inputParamsResolver + * @param \Magento\WebapiAsync\Model\MessageQueue\MassSchedule $asyncBulkPublisher + * @param \Magento\WebapiAsync\Model\ConfigInterface $webapiAsyncConfig + * @param \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor + */ + public function __construct( + RestResponse $response, + InputParamsResolver $inputParamsResolver, + MassSchedule $asyncBulkPublisher, + WebApiAsyncConfig $webapiAsyncConfig, + DataObjectProcessor $dataObjectProcessor + ) { + $this->response = $response; + $this->inputParamsResolver = $inputParamsResolver; + $this->asyncBulkPublisher = $asyncBulkPublisher; + $this->webapiAsyncConfig = $webapiAsyncConfig; + $this->dataObjectProcessor = $dataObjectProcessor; + } + + /** + * {@inheritdoc} + */ + public function process(\Magento\Framework\Webapi\Rest\Request $request) + { + $request->setPathInfo( + str_replace( + self::PROCESSOR_PATH, + SynchronousRequestProcessor::PROCESSOR_PATH, + $request->getPathInfo() + ) + ); + + try { + $entitiesParamsArray = $this->inputParamsResolver->resolve(); + $topicName = $this->getTopicName($request); + + /** @var \Magento\WebapiAsync\Api\Data\AsyncResponseInterface $asyncResponse */ + $asyncResponse = $this->asyncBulkPublisher->publishMass( + $topicName, + $entitiesParamsArray + ); + + $responseData = $this->dataObjectProcessor->buildOutputDataArray( + $asyncResponse, + \Magento\WebapiAsync\Api\Data\AsyncResponseInterface::class + ); + + $this->response->setStatusCode(RestResponse::STATUS_CODE_202) + ->prepareResponse($responseData); + } catch (\Exception $e) { + $this->response->setException($e); + } + } + + /** + * {@inheritdoc} + */ + public function getProcessorPath() + { + return self::PROCESSOR_PATH; + } + + /** + * @param \Magento\Framework\Webapi\Rest\Request $request + * @return string + */ + private function getTopicName($request) + { + $route = $this->inputParamsResolver->getRoute(); + + return $this->webapiAsyncConfig->getTopicName( + $route->getRoutePath(), + $request->getHttpMethod() + ); + } +} diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessor.php b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessor.php new file mode 100644 index 0000000000000..497496e1af6f4 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessor.php @@ -0,0 +1,71 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Controller\Rest; + +use Magento\Webapi\Model\Rest\Swagger\Generator; +use Magento\Framework\Webapi\Rest\Response as RestResponse; +use Magento\Framework\Webapi\Request; +use Magento\Webapi\Controller\Rest\RequestProcessorInterface; + +class AsynchronousSchemaRequestProcessor implements RequestProcessorInterface +{ + + /** + * Path for accessing Async Rest API schema + */ + const PROCESSOR_PATH = 'async/schema'; + + /** + * @var \Magento\Webapi\Model\Rest\Swagger\Generator + */ + private $swaggerGenerator; + + /** + * @var \Magento\Framework\Webapi\Rest\Response + */ + private $response; + + /** + * Initial dependencies + * + * @param \Magento\Webapi\Model\Rest\Swagger\Generator $swaggerGenerator + * @param \Magento\Framework\Webapi\Rest\Response $response + */ + public function __construct( + Generator $swaggerGenerator, + RestResponse $response + ) { + $this->swaggerGenerator = $swaggerGenerator; + $this->response = $response; + } + + /** + * {@inheritdoc} + */ + public function process(\Magento\Framework\Webapi\Rest\Request $request) + { + $requestedServices = $request->getRequestedServices('all'); + $requestedServices = $requestedServices == Request::ALL_SERVICES + ? $this->swaggerGenerator->getListOfServices() + : $requestedServices; + $responseBody = $this->swaggerGenerator->generate( + $requestedServices, + $request->getScheme(), + $request->getHttpHost(), + $request->getRequestUri() + ); + $this->response->setBody($responseBody)->setHeader('Content-Type', 'application/json'); + } + + /** + * {@inheritdoc} + */ + public function getProcessorPath() + { + return self::PROCESSOR_PATH; + } +} diff --git a/app/code/Magento/WebapiAsync/LICENSE.txt b/app/code/Magento/WebapiAsync/LICENSE.txt new file mode 100644 index 0000000000000..49525fd99da9c --- /dev/null +++ b/app/code/Magento/WebapiAsync/LICENSE.txt @@ -0,0 +1,48 @@ + +Open Software License ("OSL") v. 3.0 + +This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: + +Licensed under the Open Software License version 3.0 + + 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: + + 1. to reproduce the Original Work in copies, either alone or as part of a collective work; + + 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; + + 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License; + + 4. to perform the Original Work publicly; and + + 5. to display the Original Work publicly. + + 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. + + 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. + + 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. + + 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). + + 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. + + 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. + + 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. + + 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including 'fair use' or 'fair dealing'). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). + + 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. + + 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. + + 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. + + 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. + + 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. + + 16. Modification of This License. This License is Copyright (C) 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. \ No newline at end of file diff --git a/app/code/Magento/WebapiAsync/LICENSE_AFL.txt b/app/code/Magento/WebapiAsync/LICENSE_AFL.txt new file mode 100644 index 0000000000000..f39d641b18a19 --- /dev/null +++ b/app/code/Magento/WebapiAsync/LICENSE_AFL.txt @@ -0,0 +1,48 @@ + +Academic Free License ("AFL") v. 3.0 + +This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: + +Licensed under the Academic Free License version 3.0 + + 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: + + 1. to reproduce the Original Work in copies, either alone or as part of a collective work; + + 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; + + 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor's reserved rights and remedies, in this Academic Free License; + + 4. to perform the Original Work publicly; and + + 5. to display the Original Work publicly. + + 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. + + 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. + + 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. + + 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). + + 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. + + 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. + + 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. + + 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). + + 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. + + 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. + + 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. + + 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. + + 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. + + 16. Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. diff --git a/app/code/Magento/WebapiAsync/Model/AsyncResponse.php b/app/code/Magento/WebapiAsync/Model/AsyncResponse.php new file mode 100644 index 0000000000000..d5cfff5ebed4b --- /dev/null +++ b/app/code/Magento/WebapiAsync/Model/AsyncResponse.php @@ -0,0 +1,63 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Model; + +use Magento\WebapiAsync\Api\Data\AsyncResponseInterface; +use Magento\Framework\DataObject; +use Magento\Framework\Api\ExtensibleDataInterface; + +class AsyncResponse extends DataObject implements AsyncResponseInterface, ExtensibleDataInterface +{ + /** + * @inheritDoc + */ + public function getBulkUuid() + { + return $this->getData(self::BULK_UUID); + } + + /** + * @inheritDoc + */ + public function setBulkUuid($bulkUuid) + { + return $this->setData(self::BULK_UUID, $bulkUuid); + } + + /** + * @inheritDoc + */ + public function getRequestItems() + { + return $this->getData(self::REQUEST_ITEMS); + } + + /** + * @inheritDoc + */ + public function setRequestItems(\Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface $requestItems) + { + return $this->setData(self::REQUEST_ITEMS, $requestItems); + } + + /** + * @inheritDoc + */ + public function getExtensionAttributes() + { + return $this->getData(self::EXTENSION_ATTRIBUTES_KEY); + } + + /** + * @inheritDoc + */ + public function setExtensionAttributes( + \Magento\WebapiAsync\Api\Data\AsyncResponseExtensionInterface $extensionAttributes + ) { + return $this->setData(self::EXTENSION_ATTRIBUTES_KEY, $extensionAttributes); + } +} diff --git a/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemStatus.php b/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemStatus.php new file mode 100644 index 0000000000000..6f03ddd8440e7 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemStatus.php @@ -0,0 +1,101 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Model\AsyncResponse; + +use Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterface; +use Magento\Framework\DataObject; + +class ItemStatus extends DataObject implements ItemStatusInterface +{ + /** + * @inheritDoc + */ + public function getId() + { + return $this->getData(self::ENTITY_ID); + } + + /** + * @inheritDoc + */ + public function setId($entityId) + { + return $this->setData(self::ENTITY_ID, $entityId); + } + + /** + * @inheritDoc + */ + public function getDataHash() + { + return $this->getData(self::DATA_HASH); + } + + /** + * @inheritDoc + */ + public function setDataHash($hash) + { + return $this->setData(self::DATA_HASH, $hash); + } + + /** + * @inheritDoc + */ + public function getStatus() + { + return $this->getData(self::STATUS); + } + + /** + * @inheritDoc + */ + public function setStatus($status = self::STATUS_ACCEPTED) + { + return $this->setData(self::STATUS, $status); + } + + /** + * @inheritDoc + */ + public function getErrorMessage() + { + return $this->getData(self::ERROR_MESSAGE); + } + + /** + * @inheritDoc + */ + public function setErrorMessage($errorMessage = null) + { + if ($errorMessage instanceof \Exception) { + $errorMessage = $errorMessage->getMessage(); + } + + return $this->setData(self::ERROR_MESSAGE, $errorMessage); + } + + /** + * @inheritDoc + */ + public function getErrorCode() + { + return $this->getData(self::ERROR_CODE); + } + + /** + * @inheritDoc + */ + public function setErrorCode($errorCode = null) + { + if ($errorCode instanceof \Exception) { + $errorCode = $errorCode->getCode(); + } + + return $this->setData(self::ERROR_CODE, (int) $errorCode); + } +} diff --git a/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemsList.php b/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemsList.php new file mode 100644 index 0000000000000..c15dad327eab6 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemsList.php @@ -0,0 +1,33 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Model\AsyncResponse; + +use Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface; + +class ItemsList implements ItemsListInterface +{ + /** + * @var array + */ + private $items; + + /** + * @param array $items [optional] + */ + public function __construct(array $items = []) + { + $this->items = $items; + } + + /** + * @inheritdoc + */ + public function getItems() + { + return $this->items; + } +} diff --git a/app/code/Magento/WebapiAsync/Model/Config.php b/app/code/Magento/WebapiAsync/Model/Config.php new file mode 100644 index 0000000000000..adf4c17d89d29 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Model/Config.php @@ -0,0 +1,155 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Model; + +use Magento\Webapi\Model\Cache\Type\Webapi as WebapiCache; +use Magento\Webapi\Model\Config as WebapiConfig; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Webapi\Model\Config\Converter; + +class Config implements ConfigInterface +{ + /** + * @var \Magento\Webapi\Model\Cache\Type\Webapi + */ + private $cache; + + /** + * @var \Magento\Webapi\Model\Config + */ + private $webApiConfig; + + /** + * @var \Magento\Framework\Serialize\SerializerInterface + */ + private $serializer; + + /** + * @var array + */ + private $asyncServices; + + /** + * Initialize dependencies. + * + * @param \Magento\Webapi\Model\Cache\Type\Webapi $cache + * @param \Magento\Webapi\Model\Config $webApiConfig + * @param \Magento\Framework\Serialize\SerializerInterface|null $serializer + */ + public function __construct( + WebapiCache $cache, + WebapiConfig $webApiConfig, + SerializerInterface $serializer = null + ) { + $this->cache = $cache; + $this->webApiConfig = $webApiConfig; + $this->serializer = $serializer ? : ObjectManager::getInstance()->get(SerializerInterface::class); + } + + /** + * {@inheritdoc} + */ + public function getServices() + { + + if (null === $this->asyncServices) { + $services = $this->cache->load(self::CACHE_ID); + if ($services && is_string($services)) { + $this->asyncServices = $this->serializer->unserialize($services); + } else { + $this->asyncServices = $this->generateTopicsDataFromWebapiConfig(); + $this->cache->save($this->serializer->serialize($this->asyncServices), self::CACHE_ID); + } + } + + return $this->asyncServices; + } + + /** + * {@inheritdoc} + */ + public function getTopicName($routeUrl, $httpMethod) + { + $services = $this->getServices(); + $topicName = $this->generateTopicNameByRouteData( + $routeUrl, + $httpMethod + ); + + if (array_key_exists($topicName, $services) === false) { + throw new LocalizedException( + __('WebapiAsync config for "%topicName" does not exist.', ['topicName' => $topicName]) + ); + } + + return $services[$topicName][self::SERVICE_PARAM_KEY_TOPIC]; + } + + /** + * @return array + */ + private function generateTopicsDataFromWebapiConfig() + { + $webApiConfig = $this->webApiConfig->getServices(); + $services = []; + foreach ($webApiConfig[Converter::KEY_ROUTES] as $routeUrl => $routeData) { + foreach ($routeData as $httpMethod => $httpMethodData) { + $serviceInterface = $httpMethodData[Converter::KEY_SERVICE][Converter::KEY_SERVICE_CLASS]; + $serviceMethod = $httpMethodData[Converter::KEY_SERVICE][Converter::KEY_SERVICE_METHOD]; + + $topicName = $this->generateTopicNameByRouteData( + $routeUrl, + $httpMethod + ); + $services[$topicName] = [ + self::SERVICE_PARAM_KEY_INTERFACE => $serviceInterface, + self::SERVICE_PARAM_KEY_METHOD => $serviceMethod, + self::SERVICE_PARAM_KEY_TOPIC => $topicName, + ]; + } + } + + return $services; + } + + /** + * Generate topic name based on service type and method name. + * + * Perform the following conversion: + * self::TOPIC_PREFIX + /V1/products + POST => async.V1.products.POST + * + * @param string $routeUrl + * @param string $httpMethod + * @return string + */ + private function generateTopicNameByRouteData($routeUrl, $httpMethod) + { + return self::TOPIC_PREFIX . $this->generateTopicName($routeUrl, $httpMethod, '/', false); + } + + /** + * @param string $typeName + * @param string $methodName + * @param string $delimiter + * @param bool $lcfirst + * @return string + */ + private function generateTopicName($typeName, $methodName, $delimiter = '\\', $lcfirst = true) + { + $parts = explode($delimiter, ltrim($typeName, $delimiter)); + foreach ($parts as &$part) { + $part = ltrim($part, ':'); + if ($lcfirst === true) { + $part = lcfirst($part); + } + } + + return implode('.', $parts) . '.' . $methodName; + } +} diff --git a/app/code/Magento/WebapiAsync/Model/ConfigInterface.php b/app/code/Magento/WebapiAsync/Model/ConfigInterface.php new file mode 100644 index 0000000000000..7a2683da71864 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Model/ConfigInterface.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Model; + +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Communication\ConfigInterface as CommunicationConfig; +use Magento\AsynchronousOperations\Api\Data\OperationInterface; +use Magento\Framework\Communication\Config\ReflectionGenerator; + +/** + * Class for accessing to Webapi_Async configuration. + * + * @api + * @since 100.3.0 + */ +interface ConfigInterface +{ + const CACHE_ID = 'webapi_async_config'; + + const TOPIC_PREFIX = 'async.'; + + const DEFAULT_CONSUMER_INSTANCE = \Magento\WebapiAsync\Model\MessageQueue\MassConsumer::class; + const DEFAULT_CONSUMER_CONNECTION = 'amqp'; + const DEFAULT_CONSUMER_MAX_MESSAGE = null; + + const SERVICE_PARAM_KEY_INTERFACE = 'interface'; + const SERVICE_PARAM_KEY_METHOD = 'method'; + const SERVICE_PARAM_KEY_TOPIC = 'topic'; + + const DEFAULT_HANDLER_NAME = 'async'; + + const SYSTEM_TOPIC_NAME = 'async.system.required.wrapper.topic'; + const SYSTEM_TOPIC_CONFIGURATION = [ + CommunicationConfig::TOPIC_NAME => self::SYSTEM_TOPIC_NAME, + CommunicationConfig::TOPIC_IS_SYNCHRONOUS => false, + CommunicationConfig::TOPIC_REQUEST => OperationInterface::class, + CommunicationConfig::TOPIC_REQUEST_TYPE => CommunicationConfig::TOPIC_REQUEST_TYPE_CLASS, + CommunicationConfig::TOPIC_RESPONSE => null, + CommunicationConfig::TOPIC_HANDLERS => [], + ]; + + /** + * Get array of generated topics name and related to this topic service class and methods + * + * @return array + * @since 100.3.0 + */ + public function getServices(); + + /** + * Get topic name from webapi_async_config services config array by route url and http method + * + * @param string $routeUrl + * @param string $httpMethod GET|POST|PUT|DELETE + * @return string + * @throws \Magento\Framework\Exception\LocalizedException + * @since 100.3.0 + */ + public function getTopicName($routeUrl, $httpMethod); +} diff --git a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassConsumer.php b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassConsumer.php new file mode 100644 index 0000000000000..9d5de50451997 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassConsumer.php @@ -0,0 +1,263 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Model\MessageQueue; + +use Magento\Framework\App\ResourceConnection; +use Psr\Log\LoggerInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\TemporaryStateExceptionInterface; +use Magento\Framework\DB\Adapter\ConnectionException; +use Magento\Framework\DB\Adapter\DeadlockException; +use Magento\Framework\DB\Adapter\LockWaitException; +use Magento\Framework\MessageQueue\MessageLockException; +use Magento\Framework\MessageQueue\ConnectionLostException; +use Magento\Framework\Exception\NotFoundException; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\MessageQueue\CallbackInvoker; +use Magento\Framework\MessageQueue\MessageValidator; +use Magento\Framework\MessageQueue\MessageEncoder; +use Magento\Framework\MessageQueue\ConsumerConfigurationInterface; +use Magento\Framework\MessageQueue\EnvelopeInterface; +use Magento\Framework\MessageQueue\QueueInterface; +use Magento\Framework\MessageQueue\LockInterface; +use Magento\Framework\MessageQueue\MessageController; +use Magento\Framework\MessageQueue\ConsumerInterface; +use Magento\Framework\Serialize\Serializer\Json; +use Magento\AsynchronousOperations\Api\Data\OperationInterface; +use Magento\Framework\Bulk\OperationManagementInterface; +use Magento\WebapiAsync\Model\ConfigInterface as AsyncConfig; + +/** + * Class Consumer used to process OperationInterface messages. + * This could be used for both synchronous and asynchronous processing, depending on topic. + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class MassConsumer implements ConsumerInterface +{ + + /** + * @var \Magento\Framework\MessageQueue\CallbackInvoker + */ + private $invoker; + + /** + * @var \Magento\Framework\MessageQueue\MessageEncoder + */ + private $messageEncoder; + + /** + * @var \Magento\Framework\MessageQueue\MessageValidator + */ + private $messageValidator; + + /** + * @var \Magento\Framework\App\ResourceConnection + */ + private $resource; + + /** + * @var \Magento\Framework\MessageQueue\ConsumerConfigurationInterface + */ + private $configuration; + + /** + * @var \Magento\Framework\Serialize\Serializer\Json + */ + private $jsonHelper; + + /** + * @var \Magento\Framework\Bulk\OperationManagementInterface + */ + private $operationManagement; + + /** + * @var \Magento\Framework\MessageQueue\MessageController + */ + private $messageController; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * Initialize dependencies. + * + * @param \Magento\Framework\MessageQueue\CallbackInvoker $invoker + * @param \Magento\Framework\MessageQueue\MessageValidator $messageValidator + * @param \Magento\Framework\MessageQueue\MessageEncoder $messageEncoder + * @param \Magento\Framework\App\ResourceConnection $resource + * @param \Magento\Framework\MessageQueue\ConsumerConfigurationInterface $configuration + * @param \Magento\Framework\Serialize\Serializer\Json $jsonHelper + * @param \Magento\Framework\Bulk\OperationManagementInterface $operationManagement + * @param \Magento\Framework\MessageQueue\MessageController $messageController + * @param \Psr\Log\LoggerInterface|null $logger + */ + public function __construct( + CallbackInvoker $invoker, + MessageValidator $messageValidator, + MessageEncoder $messageEncoder, + ResourceConnection $resource, + ConsumerConfigurationInterface $configuration, + Json $jsonHelper, + OperationManagementInterface $operationManagement, + MessageController $messageController, + LoggerInterface $logger = null + ) { + $this->invoker = $invoker; + $this->messageValidator = $messageValidator; + $this->messageEncoder = $messageEncoder; + $this->resource = $resource; + $this->configuration = $configuration; + $this->jsonHelper = $jsonHelper; + $this->operationManagement = $operationManagement; + $this->messageController = $messageController; + + $this->logger = $logger ? : \Magento\Framework\App\ObjectManager::getInstance()->get(LoggerInterface::class); + } + + /** + * {@inheritdoc} + */ + public function process($maxNumberOfMessages = null) + { + $queue = $this->configuration->getQueue(); + + if (!isset($maxNumberOfMessages)) { + $queue->subscribe($this->getTransactionCallback($queue)); + } else { + $this->invoker->invoke($queue, $maxNumberOfMessages, $this->getTransactionCallback($queue)); + } + } + + /** + * Get transaction callback. This handles the case of async. + * + * @param QueueInterface $queue + * @return \Closure + */ + private function getTransactionCallback(QueueInterface $queue) + { + return function (EnvelopeInterface $message) use ($queue) { + /** @var LockInterface $lock */ + $lock = null; + try { + $topicName = $message->getProperties()['topic_name']; + $lock = $this->messageController->lock($message, $this->configuration->getConsumerName()); + + $allowedTopics = $this->configuration->getTopicNames(); + if (in_array($topicName, $allowedTopics)) { + $this->dispatchMessage($message); + } else { + $queue->reject($message); + + return; + } + + $queue->acknowledge($message); + } catch (MessageLockException $exception) { + $queue->acknowledge($message); + } catch (ConnectionLostException $e) { + if ($lock) { + $this->resource->getConnection() + ->delete($this->resource->getTableName('queue_lock'), ['id = ?' => $lock->getId()]); + } + } catch (NotFoundException $e) { + $queue->acknowledge($message); + $this->logger->warning($e->getMessage()); + } catch (\Exception $e) { + $queue->reject($message, false, $e->getMessage()); + if ($lock) { + $this->resource->getConnection() + ->delete($this->resource->getTableName('queue_lock'), ['id = ?' => $lock->getId()]); + } + } + }; + } + + /** + * Decode OperationInterface message and process them. + * Invokes service contract handler with the input params. + * Updates the status of the mass operation. + * + * @param EnvelopeInterface $message + * @throws LocalizedException + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ + private function dispatchMessage(EnvelopeInterface $message) + { + $operation = $this->messageEncoder->decode(AsyncConfig::SYSTEM_TOPIC_NAME, $message->getBody()); + $this->messageValidator->validate(AsyncConfig::SYSTEM_TOPIC_NAME, $operation); + + $status = OperationInterface::STATUS_TYPE_COMPLETE; + $errorCode = null; + $messages = []; + $topicName = $operation->getTopicName(); + $handlers = $this->configuration->getHandlers($topicName); + try { + $data = $this->jsonHelper->unserialize($operation->getSerializedData()); + $entityParams = $this->messageEncoder->decode($topicName, $data['meta_information']); + $this->messageValidator->validate($topicName, $entityParams); + } catch (\Exception $e) { + $this->logger->critical($e->getMessage()); + $status = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED; + $errorCode = $e->getCode(); + $messages[] = $e->getMessage(); + } + + if ($errorCode === null) { + foreach ($handlers as $callback) { + try { + call_user_func_array($callback, $entityParams); + $messages[] = sprintf('Service execution success %s::%s', get_class($callback[0]), $callback[1]); + } catch (\Zend_Db_Adapter_Exception $e) { + $this->logger->critical($e->getMessage()); + if ($e instanceof LockWaitException + || $e instanceof DeadlockException + || $e instanceof ConnectionException + ) { + $status = OperationInterface::STATUS_TYPE_RETRIABLY_FAILED; + $errorCode = $e->getCode(); + $messages[] = __($e->getMessage()); + } else { + $status = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED; + $errorCode = $e->getCode(); + $messages[] = + __('Sorry, something went wrong during product prices update. Please see log for details.'); + } + } catch (NoSuchEntityException $e) { + $this->logger->critical($e->getMessage()); + $status = ($e instanceof TemporaryStateExceptionInterface) ? + OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED : + OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED; + $errorCode = $e->getCode(); + $messages[] = $e->getMessage(); + } catch (LocalizedException $e) { + $this->logger->critical($e->getMessage()); + $status = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED; + $errorCode = $e->getCode(); + $messages[] = $e->getMessage(); + } catch (\Exception $e) { + $this->logger->critical($e->getMessage()); + $status = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED; + $errorCode = $e->getCode(); + $messages[] = $e->getMessage(); + } + } + } + + $serializedData = (isset($errorCode)) ? $operation->getSerializedData() : null; + $this->operationManagement->changeOperationStatus( + $operation->getId(), + $status, + $errorCode, + implode('; ', $messages), + $serializedData + ); + } +} diff --git a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassPublisher.php b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassPublisher.php new file mode 100644 index 0000000000000..ffdf363ebdac9 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassPublisher.php @@ -0,0 +1,104 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Model\MessageQueue; + +use Magento\Framework\MessageQueue\MessageValidator; +use Magento\Framework\MessageQueue\MessageEncoder; +use Magento\Framework\MessageQueue\Publisher\ConfigInterface as PublisherConfig; +use Magento\Framework\MessageQueue\Bulk\ExchangeRepository; +use Magento\Framework\MessageQueue\EnvelopeFactory; +use Magento\WebapiAsync\Model\ConfigInterface as AsyncConfig; +use Magento\Framework\MessageQueue\PublisherInterface; +use Magento\Framework\MessageQueue\MessageIdGeneratorInterface; + +/** + * Class MassPublisher used for encoding topic entities to OperationInterface and publish them. + */ +class MassPublisher implements PublisherInterface +{ + /** + * @var \Magento\Framework\MessageQueue\Bulk\ExchangeRepository + */ + private $exchangeRepository; + + /** + * @var \Magento\Framework\MessageQueue\EnvelopeFactory + */ + private $envelopeFactory; + + /** + * @var \Magento\Framework\MessageQueue\MessageEncoder + */ + private $messageEncoder; + + /** + * @var \Magento\Framework\MessageQueue\MessageValidator + */ + private $messageValidator; + + /** + * @var \Magento\Framework\MessageQueue\Publisher\ConfigInterface + */ + private $publisherConfig; + + /** + * @var \Magento\Framework\MessageQueue\MessageIdGeneratorInterface + */ + private $messageIdGenerator; + + /** + * Initialize dependencies. + * + * @param \Magento\Framework\MessageQueue\Bulk\ExchangeRepository $exchangeRepository + * @param \Magento\Framework\MessageQueue\EnvelopeFactory $envelopeFactory + * @param \Magento\Framework\MessageQueue\MessageEncoder $messageEncoder + * @param \Magento\Framework\MessageQueue\MessageValidator $messageValidator + * @param \Magento\Framework\MessageQueue\Publisher\ConfigInterface $publisherConfig + * @param \Magento\Framework\MessageQueue\MessageIdGeneratorInterface $messageIdGenerator + */ + public function __construct( + ExchangeRepository $exchangeRepository, + EnvelopeFactory $envelopeFactory, + MessageEncoder $messageEncoder, + MessageValidator $messageValidator, + PublisherConfig $publisherConfig, + MessageIdGeneratorInterface $messageIdGenerator + ) { + $this->exchangeRepository = $exchangeRepository; + $this->envelopeFactory = $envelopeFactory; + $this->messageEncoder = $messageEncoder; + $this->messageValidator = $messageValidator; + $this->publisherConfig = $publisherConfig; + $this->messageIdGenerator = $messageIdGenerator; + } + + /** + * {@inheritdoc} + */ + public function publish($topicName, $data) + { + $envelopes = []; + foreach ($data as $message) { + $this->messageValidator->validate(AsyncConfig::SYSTEM_TOPIC_NAME, $message); + $message = $this->messageEncoder->encode(AsyncConfig::SYSTEM_TOPIC_NAME, $message); + $envelopes[] = $this->envelopeFactory->create( + [ + 'body' => $message, + 'properties' => [ + 'delivery_mode' => 2, + 'message_id' => $this->messageIdGenerator->generate($topicName), + ] + ] + ); + } + $publisher = $this->publisherConfig->getPublisher($topicName); + $connectionName = $publisher->getConnection()->getName(); + $exchange = $this->exchangeRepository->getByConnectionName($connectionName); + $exchange->enqueue($topicName, $envelopes); + return null; + } +} diff --git a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php new file mode 100644 index 0000000000000..221a149a8c85d --- /dev/null +++ b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php @@ -0,0 +1,230 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Model\MessageQueue; + +use Magento\AsynchronousOperations\Api\Data\OperationInterface; +use Magento\AsynchronousOperations\Api\Data\OperationInterfaceFactory; +use Magento\Framework\DataObject\IdentityGeneratorInterface; +use Magento\Authorization\Model\UserContextInterface; +use Magento\Framework\EntityManager\EntityManager; +use Magento\WebapiAsync\Api\Data\AsyncResponseInterfaceFactory; +use Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterfaceFactory; +use Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterfaceFactory; +use Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterface; +use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterfaceFactory; +use Magento\Framework\MessageQueue\MessageValidator; +use Magento\Framework\MessageQueue\MessageEncoder; +use Magento\Framework\Bulk\BulkManagementInterface; +use Psr\Log\LoggerInterface; +use Magento\Framework\Serialize\Serializer\Json; + +/** + * Class MassPublisher used for encoding topic entities to OperationInterface and publish them. + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class MassSchedule +{ + /** + * @var \Magento\AsynchronousOperations\Api\Data\OperationInterfaceFactory + */ + private $operationFactory; + + /** + * @var \Magento\Framework\DataObject\IdentityGeneratorInterface + */ + private $identityService; + + /** + * @var \Magento\Authorization\Model\UserContextInterface + */ + private $userContext; + + /** + * @var \Magento\Framework\Serialize\Serializer\Json + */ + private $jsonHelper; + + /** + * @var \Magento\Framework\EntityManager\EntityManager + */ + private $entityManager; + + /** + * @var \Magento\WebapiAsync\Api\Data\AsyncResponseInterfaceFactory + */ + private $asyncResponseFactory; + + /** + * @var \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterfaceFactory + */ + private $itemsListInterfaceFactory; + + /** + * @var \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterfaceFactory + */ + private $itemStatusInterfaceFactory; + + /** + * @var BulkSummaryInterfaceFactory + */ + private $bulkSummaryFactory; + + /** + * @var \Psr\Log\LoggerInterface + */ + private $logger; + + /** + * @var MessageEncoder + */ + private $messageEncoder; + + /** + * @var MessageValidator + */ + private $messageValidator; + + /** + * @var \Magento\Framework\Bulk\BulkManagementInterface + */ + private $bulkManagement; + + /** + * Initialize dependencies. + * + * @param \Magento\AsynchronousOperations\Api\Data\OperationInterfaceFactory $operationFactory + * @param \Magento\Framework\DataObject\IdentityGeneratorInterface $identityService + * @param \Magento\Authorization\Model\UserContextInterface $userContextInterface + * @param \Magento\Framework\Serialize\Serializer\Json $jsonHelper + * @param \Magento\Framework\EntityManager\EntityManager $entityManager + * @param \Magento\WebapiAsync\Api\Data\AsyncResponseInterfaceFactory $asyncResponse + * @param \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterfaceFactory $itemsListFactory + * @param \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterfaceFactory $itemStatusFactory + * @param \Magento\AsynchronousOperations\Api\Data\BulkSummaryInterfaceFactory $bulkSummaryFactory + * @param \Magento\Framework\MessageQueue\MessageEncoder $messageEncoder + * @param \Magento\Framework\MessageQueue\MessageValidator $messageValidator + * @param \Magento\Framework\Bulk\BulkManagementInterface $bulkManagement + * @param \Psr\Log\LoggerInterface $logger + */ + public function __construct( + OperationInterfaceFactory $operationFactory, + IdentityGeneratorInterface $identityService, + UserContextInterface $userContextInterface, + Json $jsonHelper, + EntityManager $entityManager, + AsyncResponseInterfaceFactory $asyncResponse, + ItemsListInterfaceFactory $itemsListFactory, + ItemStatusInterfaceFactory $itemStatusFactory, + BulkSummaryInterfaceFactory $bulkSummaryFactory, + MessageEncoder $messageEncoder, + MessageValidator $messageValidator, + BulkManagementInterface $bulkManagement, + LoggerInterface $logger + ) { + $this->userContext = $userContextInterface; + $this->operationFactory = $operationFactory; + $this->identityService = $identityService; + $this->jsonHelper = $jsonHelper; + $this->entityManager = $entityManager; + $this->asyncResponseFactory = $asyncResponse; + $this->itemsListInterfaceFactory = $itemsListFactory; + $this->itemStatusInterfaceFactory = $itemStatusFactory; + $this->bulkSummaryFactory = $bulkSummaryFactory; + $this->messageEncoder = $messageEncoder; + $this->messageValidator = $messageValidator; + $this->bulkManagement = $bulkManagement; + + $this->logger = $logger ? : \Magento\Framework\App\ObjectManager::getInstance()->get(LoggerInterface::class); + } + + /** + * Schedule new bulk operation + * + * @param string $topicName + * @param array $entitiesArray + * @param null|string $groupId + * @throws \Magento\Framework\Exception\LocalizedException + * @return \Magento\WebapiAsync\Api\Data\AsyncResponseInterface + */ + public function publishMass($topicName, $entitiesArray, $groupId = null) + { + $bulkDescription = sprintf('Topic %s', $topicName); + $userId = $this->userContext->getUserId(); + + /** + * set admin userId to 1 because seems it's not work with oAuth + * and we need set user id manually + */ + if (!isset($userId) || $userId == 0) { + $userId = 1; + } + + if ($groupId == null) { + $groupId = $this->identityService->generateId(); + + /** create new bulk without operations */ + $this->bulkManagement->scheduleBulk($groupId, [], $bulkDescription, $userId); + } + /** @var \Magento\WebapiAsync\Api\Data\AsyncResponseInterface $asyncResponse */ + $asyncResponse = $this->asyncResponseFactory->create(); + $asyncResponse->setBulkUuid($groupId); + + $operations = []; + $requestItems = []; + foreach ($entitiesArray as $key => $entityParams) { + /** @var \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterface $requestItem */ + $requestItem = $this->itemStatusInterfaceFactory->create(); + + try { + $this->messageValidator->validate($topicName, $entityParams); + $data = $this->messageEncoder->encode($topicName, $entityParams); + + $serializedData = [ + 'entity_id' => null, + 'entity_link' => '', + 'meta_information' => $data, + ]; + $data = [ + 'data' => [ + OperationInterface::BULK_ID => $groupId, + OperationInterface::TOPIC_NAME => $topicName, + OperationInterface::SERIALIZED_DATA => $this->jsonHelper->serialize($serializedData), + OperationInterface::STATUS => OperationInterface::STATUS_TYPE_OPEN, + ], + ]; + + /** @var \Magento\AsynchronousOperations\Api\Data\OperationInterface $operation */ + $operation = $this->operationFactory->create($data); + $operations[] = $this->entityManager->save($operation); + + $requestItem->setId($key); + $requestItem->setStatus(ItemStatusInterface::STATUS_ACCEPTED); + } catch (\Exception $exception) { + $requestItem->setId($key); + $requestItem->setStatus(ItemStatusInterface::STATUS_REJECTED); + $requestItem->setErrorMessage($exception); + $requestItem->setErrorCode($exception); + } + + $requestItems[] = $requestItem; + } + + $result = $this->bulkManagement->scheduleBulk($groupId, $operations, $bulkDescription, $userId); + + if (!$result) { + throw new \Magento\Framework\Exception\LocalizedException( + __('Something went wrong while processing the request.') + ); + } + + /** @var \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface $itemsResponseList */ + $requestItemsList = $this->itemsListInterfaceFactory->create(['items' => $requestItems]); + $asyncResponse->setRequestItems($requestItemsList); + + return $asyncResponse; + } +} diff --git a/app/code/Magento/WebapiAsync/README.md b/app/code/Magento/WebapiAsync/README.md new file mode 100644 index 0000000000000..ed57634e77caf --- /dev/null +++ b/app/code/Magento/WebapiAsync/README.md @@ -0,0 +1,3 @@ +# WebapiAsync + +**WebapiAsync** Extends Webapi extension and provide functional to process asynchronous requests. It handle asynchronous requests, schedule, publish and consum bulk operations from queue. diff --git a/app/code/Magento/WebapiAsync/Test/ApiFunctional/BulkScheduleTest.php b/app/code/Magento/WebapiAsync/Test/ApiFunctional/BulkScheduleTest.php new file mode 100644 index 0000000000000..3473f8fe5f120 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Test/ApiFunctional/BulkScheduleTest.php @@ -0,0 +1,466 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Test\Async; + +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\TestFramework\TestCase\WebapiAbstract; +use Magento\Framework\MessageQueue\Consumer\ConfigInterface as ConsumerConfigInterface; +use Magento\MessageQueue\Model\Cron\ConsumersRunner\PidConsumerManager; +use Magento\Framework\App\DeploymentConfig\FileReader; +use Magento\Framework\App\DeploymentConfig\Writer; +use Magento\Framework\Config\File\ConfigFilePool; +use Magento\Framework\ShellInterface; +use Magento\Framework\Filesystem; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\App\Config\ReinitableConfigInterface; + +/** + * Check async request for product creation service, scheduling bulk to rabbitmq + * running consumers and check async.opearion.add consumer + * check if product was created by async requests + * + * @magentoAppIsolation enabled + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class BulkScheduleTest extends WebapiAbstract +{ + const SERVICE_NAME = 'catalogProductRepositoryV1'; + const SERVICE_VERSION = 'V1'; + const REST_RESOURCE_PATH = '/V1/products'; + const ASYNC_RESOURCE_PATH = '/async/V1/products'; + const ASYNC_CONSUMER_NAME = 'async.V1.products.POST'; + + const KEY_TIER_PRICES = 'tier_prices'; + const KEY_SPECIAL_PRICE = 'special_price'; + const KEY_CATEGORY_LINKS = 'category_links'; + + const BULK_UUID_KEY = 'bulk_uuid'; + + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + + /** + * Consumer config provider + * + * @var ConsumerConfigInterface + */ + private $consumerConfig; + + /** + * @var PidConsumerManager + */ + private $pid; + + /** + * @var FileReader + */ + private $reader; + + /** + * @var \Magento\MessageQueue\Model\Cron\ConsumersRunner + */ + private $consumersRunner; + + /** + * @var Filesystem + */ + private $filesystem; + + /** + * @var ConfigFilePool + */ + private $configFilePool; + + /** + * @var ReinitableConfigInterface + */ + private $appConfig; + + /** + * @var ShellInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shellMock; + + /** + * @var array + */ + private $config; + + /** + * @var \Magento\Framework\App\DeploymentConfig + */ + private $deploymentConfig; + + /** + * @var array + */ + private $productData = [ + [ + ProductInterface::SKU => 'simple', + ProductInterface::NAME => 'Simple Related Product', + ProductInterface::TYPE_ID => 'simple', + ProductInterface::PRICE => 10, + ], + [ + ProductInterface::SKU => 'simple_with_cross', + ProductInterface::NAME => 'Simple Product With Related Product', + ProductInterface::TYPE_ID => 'simple', + ProductInterface::PRICE => 10, + ], + ]; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->shellMock = $this->getMockBuilder(ShellInterface::class) + ->getMockForAbstractClass(); + $this->pid = $this->objectManager->get(PidConsumerManager::class); + $this->consumerConfig = $this->objectManager->get(ConsumerConfigInterface::class); + $this->reader = $this->objectManager->get(FileReader::class); + $this->filesystem = $this->objectManager->get(Filesystem::class); + $this->configFilePool = $this->objectManager->get(ConfigFilePool::class); + $this->appConfig = $this->objectManager->get(ReinitableConfigInterface::class); + + $this->consumersRunner = $this->objectManager->create( + \Magento\MessageQueue\Model\Cron\ConsumersRunner::class, + ['shellBackground' => $this->shellMock] + ); + + $this->config = $this->loadConfig(); + + $this->shellMock->expects($this->any()) + ->method('execute') + ->willReturnCallback(function ($command, $arguments) { + $command = vsprintf($command, $arguments); + $params = + \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams(); + $params['MAGE_DIRS']['base']['path'] = BP; + $params = + 'INTEGRATION_TEST_PARAMS="' . urldecode(http_build_query($params)) . '"'; + $command = + str_replace('bin/magento', 'dev/tests/integration/bin/magento', $command); + $command = $params . ' ' . $command; + + return exec("{$command} > /dev/null &"); + }); + } + + /** + * @dataProvider productCreationProvider + */ + public function testAsyncScheduleBulk($product) + { + $response = $this->saveProductAsync($product); + $this->assertArrayHasKey(self::BULK_UUID_KEY, $response); + $this->assertNotNull($response[self::BULK_UUID_KEY]); + } + + /** + * @param string $sku + * @param string|null $storeCode + * @return array|bool|float|int|string + */ + private function getProduct($sku, $storeCode = null) + { + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::REST_RESOURCE_PATH . '/' . $sku, + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + ], + ]; + + $response = $this->_webApiCall($serviceInfo, [ProductInterface::SKU => $sku], null, $storeCode); + + return $response; + } + + /** + * @return array + */ + public function productCreationProvider() + { + $productBuilder = function ($data) { + return array_replace_recursive( + $this->getSimpleProductData(), + $data + ); + }; + + return [ + [$productBuilder([ProductInterface::TYPE_ID => 'simple', ProductInterface::SKU => 'psku-test-1'])], + [$productBuilder([ProductInterface::TYPE_ID => 'virtual', ProductInterface::SKU => 'psku-test-2'])], + ]; + } + + /** + * Get Simple Product Data + * + * @param array $productData + * @return array + */ + private function getSimpleProductData($productData = []) + { + return [ + ProductInterface::SKU => isset($productData[ProductInterface::SKU]) + ? $productData[ProductInterface::SKU] : uniqid('sku-', true), + ProductInterface::NAME => isset($productData[ProductInterface::NAME]) + ? $productData[ProductInterface::NAME] : uniqid('sku-', true), + ProductInterface::VISIBILITY => 4, + ProductInterface::TYPE_ID => 'simple', + ProductInterface::PRICE => 3.62, + ProductInterface::STATUS => 1, + ProductInterface::TYPE_ID => 'simple', + ProductInterface::ATTRIBUTE_SET_ID => 4, + 'custom_attributes' => [ + ['attribute_code' => 'cost', 'value' => ''], + ['attribute_code' => 'description', 'value' => 'Description'], + ], + ]; + } + + /** + * @param $product + * @param string|null $storeCode + * @return mixed + */ + private function saveProductAsync($product, $storeCode = null) + { + if (isset($product['custom_attributes'])) { + for ($i = 0; $i < sizeof($product['custom_attributes']); $i++) { + if ($product['custom_attributes'][$i]['attribute_code'] == 'category_ids' + && !is_array($product['custom_attributes'][$i]['value']) + ) { + $product['custom_attributes'][$i]['value'] = [""]; + } + } + } + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::ASYNC_RESOURCE_PATH, + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST, + ], + ]; + $requestData = ['product' => $product]; + + return $this->_webApiCall($serviceInfo, $requestData, null, $storeCode); + } + + /** + * Delete Product by rest request without async + * + * @param string $sku + * @return boolean + */ + private function deleteProductRest($sku) + { + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::REST_RESOURCE_PATH . '/' . $sku, + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE, + ], + ]; + + return $this->_webApiCall($serviceInfo, ['sku' => $sku]); + } + + /** + * Checks that pid files are created + * + * @return void + */ + public function testCheckThatAsyncPidFilesWasCreated() + { + $config = $this->config; + $config['cron_consumers_runner'] = ['cron_run' => true]; + $this->writeConfig($config); + + $this->consumersRunner->run(); + + foreach ($this->consumerConfig->getConsumers() as $consumer) { + if ($consumer->getName() == self::ASYNC_CONSUMER_NAME) { + $this->waitConsumerPidFile($consumer->getName()); + } + } + } + + /** + * Tests running of specific consumer and his re-running when it is working + * + * @return void + */ + public function testAsyncConsumerAndRerun() + { + $specificConsumer = self::ASYNC_CONSUMER_NAME; + $config = $this->config; + $config['cron_consumers_runner'] = + ['consumers' => [$specificConsumer], 'max_messages' => null, 'cron_run' => true]; + $this->writeConfig($config); + + $this->reRunConsumersAndCheckPidFiles($specificConsumer); + $this->assertGreaterThan(0, $this->pid->getPid($specificConsumer)); + } + + /** + * @dataProvider productCreationProvider + */ + public function testAsyncProductCreation($product) + { + $restProduct = $this->getProduct($product[ProductInterface::SKU]); + $this->assertArrayHasKey('id', $restProduct); + $this->assertGreaterThan(0, $restProduct['id']); + $this->deleteProductRest($product[ProductInterface::SKU]);//removing product immediately after test passed + } + + /** + * @param string $specificConsumer + * @return void + */ + private function reRunConsumersAndCheckPidFiles($specificConsumer) + { + $this->consumersRunner->run(); + + sleep(20); + + foreach ($this->consumerConfig->getConsumers() as $consumer) { + $consumerName = $consumer->getName(); + $pidFilePath = $this->pid->getPidFilePath($consumerName); + + if ($consumerName === $specificConsumer) { + $this->assertTrue(file_exists($pidFilePath)); + } else { + $this->assertFalse(file_exists($pidFilePath)); + } + } + } + + /** + * Tests disabling cron job which runs consumers + * + * @return void + */ + public function testCronJobDisabled() + { + $config = $this->config; + $config['cron_consumers_runner'] = ['cron_run' => false]; + + $this->writeConfig($config); + + $this->consumersRunner->run(); + + sleep(20); + + foreach ($this->consumerConfig->getConsumers() as $consumer) { + $pidFilePath = $this->pid->getPidFilePath($consumer->getName()); + $this->assertFalse(file_exists($pidFilePath)); + } + } + + /** + * @param string $consumerName + * @return void + */ + private function waitConsumerPidFile($consumerName) + { + $pidFilePath = $this->pid->getPidFilePath($consumerName); + $i = 0; + do { + sleep(1); + } while (!file_exists($pidFilePath) && ($i++ < 60)); + + sleep(30); + + if (!file_exists($pidFilePath)) { + $this->fail($consumerName . ' pid file does not exist.'); + } + } + + /** + * @return array + */ + private function loadConfig() + { + return $this->reader->load(ConfigFilePool::APP_ENV); + } + + /** + * @param array $config + * @return void + */ + private function writeConfig(array $config) + { + /** @var Writer $writer */ + $writer = $this->objectManager->get(Writer::class); + $writer->saveConfig([ConfigFilePool::APP_ENV => $config]); + } + + /** + * @inheritdoc + */ + private function tearDown() + { + foreach ($this->consumerConfig->getConsumers() as $consumer) { + $consumerName = $consumer->getName(); + $pid = $this->pid->getPid($consumerName); + + if ($pid && $this->pid->isRun($consumerName)) { + posix_kill($pid, SIGKILL); + } + + $path = $this->pid->getPidFilePath($consumerName); + if (file_exists($path)) { + unlink($path); + } + } + + $this->filesystem->getDirectoryWrite(DirectoryList::CONFIG)->writeFile( + $this->configFilePool->getPath(ConfigFilePool::APP_ENV), + "<?php\n return array();\n" + ); + $this->writeConfig($this->config); + $this->appConfig->reinit(); + } + + /** + * Mock AMQP configuration. + * + * @param bool $enabled + * @return void + */ + private function setAmqpConfiguredStatus($enabled) + { + if ($enabled) { + $data = [ + 'amqp' => + [ + 'host' => 'localhost', + 'port' => '5672', + 'user' => 'guest', + 'password' => 'guest', + 'virtualhost' => '/', + 'ssl' => '', + ], + ]; + } else { + $data = [ + 'amqp' => + [ + 'host' => '', + 'port' => '', + 'user' => '', + 'password' => '', + 'virtualhost' => '/', + 'ssl' => '', + ], + ]; + } + } +} diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php new file mode 100644 index 0000000000000..bc76a803d3cfb --- /dev/null +++ b/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php @@ -0,0 +1,66 @@ +<?php +/*** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Test\Unit\Controller; + +use Magento\Store\Model\Store; + +class PathProcessorTest extends \PHPUnit\Framework\TestCase +{ + /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Store\Model\StoreManagerInterface */ + private $storeManagerMock; + + /** @var \Magento\Webapi\Controller\PathProcessor */ + private $model; + + /** @var string */ + private $arbitraryStoreCode = 'myStoreCode'; + + /** @var string */ + private $endpointPath = '/async/V1/path/of/endpoint'; + + protected function setUp() + { + $this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->storeManagerMock->expects($this->once()) + ->method('getStores') + ->willReturn([ + $this->arbitraryStoreCode => 'store object', + 'default' => 'default store object', + ]); + $this->model = new \Magento\Webapi\Controller\PathProcessor($this->storeManagerMock); + } + + /** + * @dataProvider processPathDataProvider + * + * @param string $storeCodeInPath + * @param string $storeCodeSet + * @param int $setCurrentStoreCallCtr + */ + public function testAllStoreCode($storeCodeInPath, $storeCodeSet, $setCurrentStoreCallCtr = 1) + { + $storeCodeInPath = !$storeCodeInPath ? : '/' . $storeCodeInPath; // add leading slash if store code not empty + $inPath = 'rest' . $storeCodeInPath . $this->endpointPath; + $this->storeManagerMock->expects($this->exactly($setCurrentStoreCallCtr)) + ->method('setCurrentStore') + ->with($storeCodeSet); + $result = $this->model->process($inPath); + $this->assertSame($this->endpointPath, $result); + } + + public function processPathDataProvider() + { + return [ + 'All store code' => ['all', Store::ADMIN_CODE], + 'Default store code' => ['', 'default', 0], + 'Arbitrary store code' => [$this->arbitraryStoreCode, $this->arbitraryStoreCode], + 'Explicit default store code' => ['default', 'default'], + ]; + } +} diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php new file mode 100644 index 0000000000000..f668c66db0058 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php @@ -0,0 +1,320 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Webapi\Test\Unit\Controller; + +use Magento\Authorization\Model\UserContextInterface; +use Magento\Framework\Exception\AuthorizationException; +use Magento\WebapiAsync\Controller\Rest\AsynchronousSchemaRequestProcessor; +use Magento\WebapiAsync\Controller\Rest\AsynchronousRequestProcessor; + +/** + * Test Rest controller. + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyFields) + */ +class RestTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Webapi\Controller\Rest + */ + private $restController; + + /** + * @var \Magento\Framework\Webapi\Rest\Request|\PHPUnit_Framework_MockObject_MockObject + */ + private $requestMock; + + /** + * @var \Magento\Framework\Webapi\Rest\Response|\PHPUnit_Framework_MockObject_MockObject + */ + private $responseMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Webapi\Controller\Rest\Router\Route + */ + private $routeMock; + + /** + * @var \stdClass|\PHPUnit_Framework_MockObject_MockObject + */ + private $serviceMock; + + /** + * @var \Magento\Framework\Oauth\OauthInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $oauthServiceMock; + + /** + * @var \Magento\Framework\Webapi\Authorization|\PHPUnit_Framework_MockObject_MockObject + */ + private $authorizationMock; + + /** + * @var \Magento\Framework\Webapi\ServiceInputProcessor|\PHPUnit_Framework_MockObject_MockObject + */ + private $serviceInputProcessorMock; + + /** + * @var \Magento\Webapi\Model\Rest\Swagger\Generator | \PHPUnit_Framework_MockObject_MockObject + */ + private $swaggerGeneratorMock; + + /** + * @var \Magento\Store\Model\StoreManagerInterface | \PHPUnit_Framework_MockObject_MockObject + */ + private $storeManagerMock; + + /** + * @var \Magento\Store\Api\Data\StoreInterface | \PHPUnit_Framework_MockObject_MockObject + */ + private $storeMock; + + /** + * @var \Magento\WebapiAsync\Controller\Rest\AsynchronousSchemaRequestProcessor | + * \PHPUnit_Framework_MockObject_MockObject + */ + private $asyncSchemaRequestProcessor; + + /** + * @var \Magento\WebapiAsync\Controller\Rest\AsynchronousRequestProcessor | + * \PHPUnit_Framework_MockObject_MockObject + */ + private $asyncRequestProcessor; + + /** + * @var \Magento\Webapi\Controller\Rest\RequestProcessorPool | \PHPUnit_Framework_MockObject_MockObject + */ + private $requestProcessorPool; + + const SERVICE_METHOD = 'testMethod'; + + const SERVICE_ID = \Magento\Webapi\Controller\Rest::class; + + protected function setUp() + { + $objectManagerMock = $this->createMock(\Magento\Framework\ObjectManagerInterface::class); + $this->requestMock = $this->getRequestMock(); + $this->requestMock->expects($this->any())->method('getHttpHost')->willReturn('testHostName.com'); + $this->responseMock = $this->getResponseMock(); + $routerMock = $this->getMockBuilder(\Magento\Webapi\Controller\Rest\Router::class)->setMethods(['match']) + ->disableOriginalConstructor()->getMock(); + + $this->routeMock = $this->getRouteMock(); + $this->serviceMock = $this->getMockBuilder(self::SERVICE_ID)->setMethods([self::SERVICE_METHOD]) + ->disableOriginalConstructor()->getMock(); + + $this->oauthServiceMock = $this->getMockBuilder(\Magento\Framework\Oauth\OauthInterface::class) + ->setMethods(['validateAccessTokenRequest'])->getMockForAbstractClass(); + $this->authorizationMock = $this->getMockBuilder(\Magento\Framework\Webapi\Authorization::class) + ->disableOriginalConstructor()->getMock(); + + $paramsOverriderMock = $this->getMockBuilder(\Magento\Webapi\Controller\Rest\ParamsOverrider::class) + ->setMethods(['overrideParams']) + ->disableOriginalConstructor()->getMock(); + + $dataObjectProcessorMock = $this->getMockBuilder(\Magento\Framework\Reflection\DataObjectProcessor::class) + ->disableOriginalConstructor() + ->setMethods(['getMethodReturnType']) + ->getMockForAbstractClass(); + + $layoutMock = $this->getMockBuilder(\Magento\Framework\View\LayoutInterface::class) + ->disableOriginalConstructor()->getMock(); + + $errorProcessorMock = $this->createMock(\Magento\Framework\Webapi\ErrorProcessor::class); + $errorProcessorMock->expects($this->any())->method('maskException')->will($this->returnArgument(0)); + + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->serviceInputProcessorMock = $this->getMockBuilder(\Magento\Framework\Webapi\ServiceInputProcessor::class) + ->disableOriginalConstructor()->setMethods(['process'])->getMock(); + + $areaListMock = $this->createMock(\Magento\Framework\App\AreaList::class); + $areaMock = $this->createMock(\Magento\Framework\App\AreaInterface::class); + $areaListMock->expects($this->any())->method('getArea')->will($this->returnValue($areaMock)); + $this->storeMock = $this->createMock(\Magento\Store\Api\Data\StoreInterface::class); + $this->storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class); + $this->storeManagerMock->expects($this->any())->method('getStore')->willReturn($this->storeMock); + $this->requestProcessorPool = $this->getRequestProccessotPoolMock(); + + $this->restController = + $objectManager->getObject( + \Magento\Webapi\Controller\Rest::class, + [ + 'request' => $this->requestMock, + 'response' => $this->responseMock, + 'router' => $routerMock, + 'objectManager' => $objectManagerMock, + 'layout' => $layoutMock, + 'oauthService' => $this->oauthServiceMock, + 'authorization' => $this->authorizationMock, + 'serviceInputProcessor' => $this->serviceInputProcessorMock, + 'errorProcessor' => $errorProcessorMock, + 'areaList' => $areaListMock, + 'paramsOverrider' => $paramsOverriderMock, + 'dataObjectProcessor' => $dataObjectProcessorMock, + 'storeManager' => $this->storeManagerMock, + 'requestProcessorPool' => $this->requestProcessorPool, + ] + ); + + $this->routeMock->expects($this->any())->method('getServiceClass')->will($this->returnValue(self::SERVICE_ID)); + $this->routeMock->expects($this->any())->method('getServiceMethod') + ->will($this->returnValue(self::SERVICE_METHOD)); + + $routerMock->expects($this->any())->method('match')->will($this->returnValue($this->routeMock)); + + $objectManagerMock->expects($this->any())->method('get')->will($this->returnValue($this->serviceMock)); + $this->responseMock->expects($this->any())->method('prepareResponse')->will($this->returnValue([])); + $this->serviceMock->expects($this->any())->method(self::SERVICE_METHOD)->will($this->returnValue(null)); + + $dataObjectProcessorMock->expects($this->any())->method('getMethodReturnType') + ->with(self::SERVICE_ID, self::SERVICE_METHOD) + ->will($this->returnValue('null')); + + $paramsOverriderMock->expects($this->any())->method('overrideParams')->will($this->returnValue([])); + + parent::setUp(); + } + + public function testDispatchSchemaRequest() + { + $params = [ + \Magento\Framework\Webapi\Request::REQUEST_PARAM_SERVICES => 'foo', + ]; + $this->requestMock->expects($this->any()) + ->method('getPathInfo') + ->willReturn(AsynchronousSchemaRequestProcessor::PROCESSOR_PATH); + + $this->requestMock->expects($this->any()) + ->method('getParams') + ->will($this->returnValue($params)); + + $schema = 'Some REST schema content'; + $this->swaggerGeneratorMock->expects($this->any())->method('generate')->willReturn($schema); + $this->requestProcessorPool->process($this->requestMock); + + $this->assertEquals($schema, $this->responseMock->getBody()); + } + + public function testDispatchAllSchemaRequest() + { + $params = [ + \Magento\Framework\Webapi\Request::REQUEST_PARAM_SERVICES => 'all', + ]; + $this->requestMock->expects($this->any()) + ->method('getPathInfo') + ->willReturn(AsynchronousSchemaRequestProcessor::PROCESSOR_PATH); + $this->requestMock->expects($this->any()) + ->method('getParam') + ->will( + $this->returnValueMap([ + [ + \Magento\Framework\Webapi\Request::REQUEST_PARAM_SERVICES, + null, + 'all', + ], + ]) + ); + $this->requestMock->expects($this->any()) + ->method('getParams') + ->will($this->returnValue($params)); + $this->requestMock->expects($this->any()) + ->method('getRequestedServices') + ->will($this->returnValue('all')); + + $schema = 'Some REST schema content'; + $this->swaggerGeneratorMock->expects($this->any())->method('generate')->willReturn($schema); + $this->requestProcessorPool->process($this->requestMock); + + $this->assertEquals($schema, $this->responseMock->getBody()); + } + + /** + * @return object|\Magento\Webapi\Controller\Rest\RequestProcessorPool + */ + private function getRequestProccessotPoolMock() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->swaggerGeneratorMock = $this->getMockBuilder(\Magento\Webapi\Model\Rest\Swagger\Generator::class) + ->disableOriginalConstructor() + ->setMethods(['generate', 'getListOfServices']) + ->getMockForAbstractClass(); + + $this->asyncSchemaRequestProcessor = $objectManager->getObject( + \Magento\WebapiAsync\Controller\Rest\AsynchronousSchemaRequestProcessor::class, + [ + 'swaggerGenerator' => $this->swaggerGeneratorMock, + 'response' => $this->responseMock, + ] + ); + + $this->asyncRequestProcessor = + $this->getMockBuilder(\Magento\WebapiAsync\Controller\Rest\AsynchronousRequestProcessor::class) + ->setMethods(['process']) + ->disableOriginalConstructor() + ->getMock(); + + return $objectManager->getObject( + \Magento\Webapi\Controller\Rest\RequestProcessorPool::class, + [ + 'requestProcessors' => [ + 'asyncSchema' => $this->asyncSchemaRequestProcessor, + 'async' => $this->asyncRequestProcessor, + ], + ] + ); + } + + /** + * @return \Magento\Webapi\Controller\Rest\Router\Route | \PHPUnit_Framework_MockObject_MockObject + */ + private function getRouteMock() + { + return $this->getMockBuilder(\Magento\Webapi\Controller\Rest\Router\Route::class) + ->setMethods([ + 'isSecure', + 'getServiceMethod', + 'getServiceClass', + 'getAclResources', + 'getParameters', + ]) + ->disableOriginalConstructor()->getMock(); + } + + /** + * @return \Magento\Framework\Webapi\Rest\Request|\PHPUnit_Framework_MockObject_MockObject + */ + private function getRequestMock() + { + return $this->getMockBuilder(\Magento\Framework\Webapi\Rest\Request::class) + ->setMethods( + [ + 'isSecure', + 'getRequestData', + 'getParams', + 'getParam', + 'getRequestedServices', + 'getPathInfo', + 'getHttpHost', + 'getMethod', + ] + )->disableOriginalConstructor()->getMock(); + } + + /** + * @return \Magento\Framework\Webapi\Rest\Response|\PHPUnit_Framework_MockObject_MockObject + */ + private function getResponseMock() + { + return $this->getMockBuilder(\Magento\Framework\Webapi\Rest\Response::class) + ->setMethods(['sendResponse', 'prepareResponse', 'setHeader']) + ->disableOriginalConstructor() + ->getMock(); + } +} diff --git a/app/code/Magento/WebapiAsync/composer.json b/app/code/Magento/WebapiAsync/composer.json new file mode 100644 index 0000000000000..4424d52d64328 --- /dev/null +++ b/app/code/Magento/WebapiAsync/composer.json @@ -0,0 +1,35 @@ +{ + "name": "magento/module-webapi-async", + "description": "N/A", + "config": { + "sort-packages": true + }, + "require": { + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "magento/framework": "100.3.*", + "magento/module-authorization": "100.3.*", + "magento/module-backend": "100.3.*", + "magento/module-integration": "100.3.*", + "magento/module-store": "100.3.*", + "magento/module-webapi": "100.3.*", + "magento/module-asynchronous-operations": "100.3.*" + }, + "suggest": { + "magento/module-user": "100.3.*", + "magento/module-customer": "100.3.*" + }, + "type": "magento2-module", + "version": "100.3.0-dev", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\WebapiAsync\\": "" + } + } +} diff --git a/app/code/Magento/WebapiAsync/etc/di.xml b/app/code/Magento/WebapiAsync/etc/di.xml new file mode 100755 index 0000000000000..954c703c8a8b5 --- /dev/null +++ b/app/code/Magento/WebapiAsync/etc/di.xml @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + + <preference for="Magento\WebapiAsync\Model\ConfigInterface" type="Magento\WebapiAsync\Model\Config" /> + <preference for="Magento\WebapiAsync\Api\Data\AsyncResponseInterface" type="Magento\WebapiAsync\Model\AsyncResponse" /> + <preference for="Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterface" type="Magento\WebapiAsync\Model\AsyncResponse\ItemStatus" /> + <preference for="Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface" type="Magento\WebapiAsync\Model\AsyncResponse\ItemsList" /> + + <type name="Magento\Framework\MessageQueue\MergerFactory"> + <arguments> + <argument name="mergers" xsi:type="array"> + <item name="async.#" xsi:type="string">Magento\WebapiAsync\Model\Merger</item> + </argument> + </arguments> + </type> + + <virtualType name="Magento\WebapiAsync\VirtualType\PublisherPool" type="Magento\Framework\MessageQueue\PublisherPool"> + <arguments> + <argument name="publishers" xsi:type="array"> + <item name="async" xsi:type="array"> + <item name="amqp" xsi:type="object">Magento\WebapiAsync\Model\MessageQueue\MassPublisher</item> + <item name="db" xsi:type="object">Magento\WebapiAsync\Model\MessageQueue\MassPublisher</item> + </item> + </argument> + </arguments> + </virtualType> + + <virtualType name="Magento\WebapiAsync\VirtualType\BulkManagement" type="Magento\AsynchronousOperations\Model\BulkManagement"> + <arguments> + <argument name="publisher" xsi:type="object">Magento\WebapiAsync\VirtualType\PublisherPool</argument> + </arguments> + </virtualType> + + <type name="Magento\WebapiAsync\Model\MessageQueue\MassSchedule"> + <arguments> + <argument name="bulkManagement" xsi:type="object">Magento\WebapiAsync\VirtualType\BulkManagement</argument> + </arguments> + </type> + +</config> diff --git a/app/code/Magento/WebapiAsync/etc/module.xml b/app/code/Magento/WebapiAsync/etc/module.xml new file mode 100644 index 0000000000000..3a77676805b70 --- /dev/null +++ b/app/code/Magento/WebapiAsync/etc/module.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> + <module name="Magento_WebapiAsync"> + <sequence> + <module name="Magento_Webapi"/> + <module name="Magento_AsynchronousOperations"/> + </sequence> + </module> +</config> \ No newline at end of file diff --git a/app/code/Magento/WebapiAsync/etc/queue_consumer.xml b/app/code/Magento/WebapiAsync/etc/queue_consumer.xml new file mode 100644 index 0000000000000..a9cb5a5c15443 --- /dev/null +++ b/app/code/Magento/WebapiAsync/etc/queue_consumer.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/consumer.xsd"> + <consumer name="async.operations.all" queue="async.operations.all" connection="amqp" + consumerInstance="Magento\WebapiAsync\Model\MessageQueue\MassConsumer"/> + + <consumer name="async.V1.products.POST" queue="async.V1.products.POST" connection="amqp" + consumerInstance="Magento\WebapiAsync\Model\MessageQueue\MassConsumer" + handler="Magento\Catalog\Api\ProductRepositoryInterface::save"/> +</config> \ No newline at end of file diff --git a/app/code/Magento/WebapiAsync/etc/queue_topology.xml b/app/code/Magento/WebapiAsync/etc/queue_topology.xml new file mode 100644 index 0000000000000..7dd9ca6e34454 --- /dev/null +++ b/app/code/Magento/WebapiAsync/etc/queue_topology.xml @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/topology.xsd"> + <exchange name="magento" type="topic" connection="amqp"> + <binding id="async.operations.all" topic="async.#" destinationType="queue" destination="async.operations.all"/> + <binding id="async.V1.products.POST" topic="async.V1.products.POST" destinationType="queue" destination="async.V1.products.POST"/> + </exchange> +</config> diff --git a/app/code/Magento/WebapiAsync/etc/webapi_rest/di.xml b/app/code/Magento/WebapiAsync/etc/webapi_rest/di.xml new file mode 100644 index 0000000000000..86a4392723bbf --- /dev/null +++ b/app/code/Magento/WebapiAsync/etc/webapi_rest/di.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + + <type name="Magento\Webapi\Controller\Rest\RequestProcessorPool"> + <arguments> + <argument name="requestProcessors" xsi:type="array"> + <item name="asyncSchema" xsi:type="object">Magento\WebapiAsync\Controller\Rest\AsynchronousSchemaRequestProcessor</item> + <item name="async" xsi:type="object">Magento\WebapiAsync\Controller\Rest\AsynchronousRequestProcessor</item> + </argument> + </arguments> + </type> + +</config> \ No newline at end of file diff --git a/app/code/Magento/WebapiAsync/registration.php b/app/code/Magento/WebapiAsync/registration.php new file mode 100644 index 0000000000000..d75ef52d5e8d6 --- /dev/null +++ b/app/code/Magento/WebapiAsync/registration.php @@ -0,0 +1,11 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +\Magento\Framework\Component\ComponentRegistrar::register( + \Magento\Framework\Component\ComponentRegistrar::MODULE, + 'Magento_WebapiAsync', + __DIR__ +); diff --git a/app/etc/di.xml b/app/etc/di.xml index e43a019697bba..012f4fec7bfad 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -221,6 +221,12 @@ <type name="Magento\Framework\Communication\Config\CompositeReader"> <arguments> <argument name="readers" xsi:type="array"> + <item name="asyncServiceReader" xsi:type="array"> + <item name="reader" xsi:type="object"> + Magento\WebapiAsync\Code\Generator\Config\RemoteServiceReader\Communication + </item> + <item name="sortOrder" xsi:type="string">0</item> + </item> <item name="xmlReader" xsi:type="array"> <item name="reader" xsi:type="object">Magento\Framework\Communication\Config\Reader\XmlReader</item> <item name="sortOrder" xsi:type="string">10</item> @@ -1598,6 +1604,7 @@ <type name="Magento\Framework\MessageQueue\Publisher\Config\CompositeReader"> <arguments> <argument name="readers" xsi:type="array"> + <item name="asyncServiceReader" xsi:type="object" sortOrder="0">Magento\WebapiAsync\Code\Generator\Config\RemoteServiceReader\Publisher</item> <item name="remoteServiceReader" xsi:type="object" sortOrder="10">Magento\Framework\MessageQueue\Publisher\Config\RemoteService\Reader</item> <item name="xmlReader" xsi:type="object" sortOrder="20">Magento\Framework\MessageQueue\Publisher\Config\Xml\Reader</item> <item name="envReader" xsi:type="object" sortOrder="30">Magento\Framework\MessageQueue\Publisher\Config\Env\Reader</item> diff --git a/lib/internal/Magento/Framework/MessageQueue/MergerFactory.php b/lib/internal/Magento/Framework/MessageQueue/MergerFactory.php index 0647279258ae2..c877c80e0c579 100644 --- a/lib/internal/Magento/Framework/MessageQueue/MergerFactory.php +++ b/lib/internal/Magento/Framework/MessageQueue/MergerFactory.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Framework\MessageQueue; use Magento\Framework\ObjectManagerInterface; @@ -24,7 +25,7 @@ class MergerFactory * @param ObjectManagerInterface $objectManager * @param string[] $mergers */ - public function __construct(ObjectManagerInterface $objectManager, $mergers = []) + public function __construct(ObjectManagerInterface $objectManager, $mergers) { $this->objectManager = $objectManager; $this->mergers = $mergers; @@ -37,11 +38,18 @@ public function __construct(ObjectManagerInterface $objectManager, $mergers = [] */ public function create($consumerName) { - if (!isset($this->mergers[$consumerName])) { + $matchMergerWildcard = $this->matchConsumer($consumerName); + + if (!isset($this->mergers[$consumerName]) && !isset($matchMergerWildcard)) { throw new \LogicException("Not found merger for consumer name '{$consumerName}'"); } - $mergerClassName = $this->mergers[$consumerName]; + if (isset($this->mergers[$consumerName])) { + $mergerClassName = $this->mergers[$consumerName]; + } else { + $mergerClassName = $this->mergers[$matchMergerWildcard]; + } + $merger = $this->objectManager->get($mergerClassName); if (!$merger instanceof MergerInterface) { @@ -54,4 +62,40 @@ public function create($consumerName) return $merger; } + + /** + * @param $consumerName + * @return string|null + */ + private function matchConsumer($consumerName) + { + $patterns = []; + foreach (array_keys($this->mergers) as $mergerFor) { + if (strpos($mergerFor, '*') !== false || strpos($mergerFor, '#') !== false) { + $patterns[$mergerFor] = $this->buildWildcardPattern($mergerFor); + } + } + + foreach ($patterns as $mergerKey => $pattern) { + if (preg_match($pattern, $consumerName)) { + return $mergerKey; + } + } + } + + /** + * Construct perl regexp pattern for matching topic names from wildcard key. + * + * @param string $wildcardKey + * @return string + */ + private function buildWildcardPattern($wildcardKey) + { + $pattern = '/^' . str_replace('.', '\.', $wildcardKey); + $pattern = str_replace('#', '.+', $pattern); + $pattern = str_replace('*', '[^\.]+', $pattern); + $pattern .= strpos($wildcardKey, '#') === strlen($wildcardKey) ? '/' : '$/'; + + return $pattern; + } } From 9eac874f9a9ffae90240232b6e1e0cb0fbb73dce Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" <a.vasiliev@sam-solutions.biz> Date: Tue, 20 Mar 2018 16:54:48 +0200 Subject: [PATCH 115/668] fix MessageValidator getRealType function when "bool" param type is not valid for "boolean" --- lib/internal/Magento/Framework/MessageQueue/MessageValidator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/Magento/Framework/MessageQueue/MessageValidator.php b/lib/internal/Magento/Framework/MessageQueue/MessageValidator.php index 9bc519fc87efc..3e1e84f458e7a 100644 --- a/lib/internal/Magento/Framework/MessageQueue/MessageValidator.php +++ b/lib/internal/Magento/Framework/MessageQueue/MessageValidator.php @@ -173,6 +173,7 @@ protected function validateClassType($message, $messageType, $topic) private function getRealType($message) { $type = is_object($message) ? get_class($message) : gettype($message); + $type = $type == 'boolean' ? 'bool' : $type; return $type == "integer" ? "int" : $type; } From fcacffaa4533d2ae0060acc9cf86ed285d323620 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Tue, 20 Mar 2018 10:03:20 -0500 Subject: [PATCH 116/668] MAGETWO-87655: Refactor configurable product declarative schema and improve performance --- .../Model/Options/Collection.php | 131 +++++++ .../Model/Resolver/ConfigurableVariant.php | 99 +++++ .../Model/Resolver/Options.php | 64 ++++ .../Model/Variant/Collection.php | 180 +++++++++ .../ConfigurableProductGraphQl/etc/di.xml | 19 - .../etc/graphql.xml | 21 +- .../etc/graphql/di.xml | 7 - .../ConfigurableProductViewTest.php | 349 ++++++++++-------- 8 files changed, 680 insertions(+), 190 deletions(-) create mode 100644 app/code/Magento/ConfigurableProductGraphQl/Model/Options/Collection.php create mode 100644 app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/ConfigurableVariant.php create mode 100644 app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Options.php create mode 100644 app/code/Magento/ConfigurableProductGraphQl/Model/Variant/Collection.php delete mode 100644 app/code/Magento/ConfigurableProductGraphQl/etc/di.xml diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Options/Collection.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Options/Collection.php new file mode 100644 index 0000000000000..4a44982eef862 --- /dev/null +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Options/Collection.php @@ -0,0 +1,131 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\ConfigurableProductGraphQl\Model\Options; + +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Model\Product; +use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\CollectionFactory; +use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\Collection + as AttributeCollection; +use Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute; +use Magento\Catalog\Model\ProductFactory; +use Magento\Framework\EntityManager\MetadataPool; + +/** + * Collection for fetching options for all configurable options pulled back in result set. + */ +class Collection +{ + /** + * @var CollectionFactory + */ + private $attributeCollectionFactory; + + /** + * @var ProductFactory + */ + private $productFactory; + + /** + * @var MetadataPool + */ + private $metadataPool; + + /** + * @var int[] + */ + private $productIds = []; + + /** + * @var array + */ + private $attributeMap = []; + + /** + * @param CollectionFactory $attributeCollectionFactory + * @param ProductFactory $productFactory + * @param MetadataPool $metadataPool + */ + public function __construct( + CollectionFactory $attributeCollectionFactory, + ProductFactory $productFactory, + MetadataPool $metadataPool + ) { + $this->attributeCollectionFactory = $attributeCollectionFactory; + $this->productFactory = $productFactory; + $this->metadataPool = $metadataPool; + } + + /** + * Add product id to attribute collection filter. + * + * @param int $productId + */ + public function addProductId(int $productId) : void + { + if (!in_array($productId, $this->productIds)) { + $this->productIds[] = $productId; + } + } + + /** + * Retrieve attributes for given product id + * + * @param int $productId + * @return array|null + */ + public function getAttributesByProductId(int $productId) : ?array + { + $attributes = $this->fetch(); + + if (!isset($attributes[$productId])) { + return null; + } + + return $attributes[$productId]; + } + + /** + * Fetch attribute data + * + * @return array + */ + private function fetch() : array + { + if (empty($this->productIds) || !empty($this->attributeMap)) { + return $this->attributeMap; + } + + $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); + /** @var AttributeCollection $attributeCollection */ + $attributeCollection = $this->attributeCollectionFactory->create(); + foreach ($this->productIds as $id) { + /** @var Product $product */ + $product = $this->productFactory->create(); + $product->setData($linkField, $id); + $attributeCollection->setProductFilter($product); + } + + /** @var Attribute $attribute */ + foreach ($attributeCollection->getItems() as $attribute) { + $productId = (int)$attribute->getProductId(); + if (!isset($this->attributeMap[$productId])) { + $this->attributeMap[$productId] = []; + } + + $attributeData = $attribute->getData(); + $this->attributeMap[$productId][$attribute->getId()] = $attribute->getData(); + $this->attributeMap[$productId][$attribute->getId()]['id'] = $attribute->getId(); + $this->attributeMap[$productId][$attribute->getId()]['attribute_code'] + = $attribute->getProductAttribute()->getAttributeCode(); + $this->attributeMap[$productId][$attribute->getId()]['values'] = $attributeData['options']; + } + + return $this->attributeMap; + } +} diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/ConfigurableVariant.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/ConfigurableVariant.php new file mode 100644 index 0000000000000..1441022bfaf6f --- /dev/null +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/ConfigurableVariant.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\ConfigurableProductGraphQl\Model\Resolver; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\ConfigurableProduct\Model\Product\Type\Configurable as Type; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\ConfigurableProductGraphQl\Model\Variant\Collection; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; +use Magento\ConfigurableProductGraphQl\Model\Options\Collection as OptionCollection; + +/** + * {@inheritdoc} + */ +class ConfigurableVariant implements ResolverInterface +{ + /** + * @var Collection + */ + private $variantCollection; + + /** + * @var OptionCollection + */ + private $optionCollection; + + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param Collection $variantCollection + * @param OptionCollection $optionCollection + * @param ValueFactory $valueFactory + */ + public function __construct( + Collection $variantCollection, + OptionCollection $optionCollection, + ValueFactory $valueFactory + ) { + $this->variantCollection = $variantCollection; + $this->optionCollection = $optionCollection; + $this->valueFactory = $valueFactory; + } + + /** + * Fetch and format configurable variants. + * + * {@inheritDoc} + */ + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?Value + { + if ($value['type_id'] !== Type::TYPE_CODE || !isset($value['id'])) { + return null; + } + + $this->variantCollection->addParentId((int)$value['id']); + $this->optionCollection->addProductId((int)$value['id']); + + $result = function () use ($value) { + $children = $this->variantCollection->getChildProductsByParentId((int)$value['id']) ?: []; + $options = $this->optionCollection->getAttributesByProductId((int)$value['id']) ?: []; + $variants = []; + foreach ($children as $key => $child) { + $variants[$key] = ['product' => $child]; + foreach ($options as $option) { + $code = $option['attribute_code']; + if (!isset($child[$code])) { + continue; + } + + foreach ($option['values'] as $optionValue) { + if ($optionValue['value_index'] != $child[$code]) { + continue; + } + $variants[$key]['attributes'][] = [ + 'label' => $optionValue['label'], + 'code' => $code, + 'use_default_value' => $optionValue['use_default_value'], + 'value_index' => $optionValue['value_index'] + ]; + } + } + } + + return $variants; + }; + + return $this->valueFactory->create($result); + } +} diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Options.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Options.php new file mode 100644 index 0000000000000..75387a1f4b59b --- /dev/null +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Options.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\ConfigurableProductGraphQl\Model\Resolver; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\ConfigurableProduct\Model\Product\Type\Configurable as Type; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; +use Magento\ConfigurableProductGraphQl\Model\Options\Collection as OptionCollection; + +/** + * {@inheritdoc} + */ +class Options implements ResolverInterface +{ + /** + * @var OptionCollection + */ + private $optionCollection; + + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param OptionCollection $optionCollection + * @param ValueFactory $valueFactory + */ + public function __construct( + OptionCollection $optionCollection, + ValueFactory $valueFactory + ) { + $this->optionCollection = $optionCollection; + $this->valueFactory = $valueFactory; + } + + /** + * Fetch and format configurable variants. + * + * {@inheritDoc} + */ + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?Value + { + if ($value['type_id'] !== Type::TYPE_CODE || !isset($value['id'])) { + return null; + } + + $this->optionCollection->addProductId((int)$value['id']); + + $result = function () use ($value) { + return $this->optionCollection->getAttributesByProductId((int)$value['id']) ?: []; + }; + + return $this->valueFactory->create($result); + } +} diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Variant/Collection.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Variant/Collection.php new file mode 100644 index 0000000000000..cbdb9c97ea0e5 --- /dev/null +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Variant/Collection.php @@ -0,0 +1,180 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\ConfigurableProductGraphQl\Model\Variant; + +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Model\Product; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; +use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\CollectionFactory; +use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection as ChildCollection; +use Magento\Catalog\Model\ProductFactory; +use Magento\Framework\EntityManager\MetadataPool; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product as DataProvider; + +/** + * Collection for fetching configurable child product data. + */ +class Collection +{ + /** + * @var CollectionFactory + */ + private $childCollectionFactory; + + /** + * @var ProductFactory + */ + private $productFactory; + + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + + /** + * @var DataProvider + */ + private $productDataProvider; + + /** + * @var MetadataPool + */ + private $metadataPool; + + /** + * @var FormatterInterface + */ + private $formatter; + + /** + * @var \Magento\Catalog\Model\ResourceModel\Product + */ + private $productResource; + + /** + * @var int[] + */ + private $parentIds = []; + + /** + * @var array + */ + private $childrenMap = []; + + /** + * @param CollectionFactory $childCollectionFactory + * @param ProductFactory $productFactory + * @param SearchCriteriaBuilder $searchCriteriaBuilder + * @param DataProvider $productDataProvider + * @param MetadataPool $metadataPool + * @param FormatterInterface $formatter + * @param \Magento\Catalog\Model\ResourceModel\Product $productResource + */ + public function __construct( + CollectionFactory $childCollectionFactory, + ProductFactory $productFactory, + SearchCriteriaBuilder $searchCriteriaBuilder, + DataProvider $productDataProvider, + MetadataPool $metadataPool, + FormatterInterface $formatter, + \Magento\Catalog\Model\ResourceModel\Product $productResource + ) { + $this->childCollectionFactory = $childCollectionFactory; + $this->productFactory = $productFactory; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->productDataProvider = $productDataProvider; + $this->metadataPool = $metadataPool; + $this->formatter = $formatter; + $this->productResource = $productResource; + } + + /** + * Add parent Id to collection filter + * + * @param int $id + * @return void + */ + public function addParentId(int $id) : void + { + if (!in_array($id, $this->parentIds)) { + $this->parentIds[] = $id; + } + } + + /** + * Retrieve child products from for passed in parent id. + * + * @param int $id + * @return array|null + */ + public function getChildProductsByParentId(int $id) : ?array + { + $childrenMap = $this->fetch(); + + if (!isset($childrenMap[$id])) { + return null; + } + + return $childrenMap[$id]; + } + + /** + * Fetch all children products from parent id's. + * + * @return array + */ + private function fetch() : array + { + if (empty($this->parentIds) || !empty($this->childrenMap)) { + return $this->childrenMap; + } + + $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); + /** @var ChildCollection $childCollection */ + $childCollection = $this->childCollectionFactory->create(); + foreach ($this->parentIds as $id) { + /** @var Product $product */ + $product = $this->productFactory->create(); + $product->setData($linkField, $id); + $childCollection->setProductFilter($product); + } + + $childIds = []; + foreach ($childCollection->getItems() as $childProduct) { + $childIds[] = (int)$childProduct->getData($linkField); + } + + $this->searchCriteriaBuilder->addFilter($linkField, $childIds, 'in'); + $childProducts = $this->productDataProvider->getList($this->searchCriteriaBuilder->create()); + + /** @var Product $childProduct */ + foreach ($childProducts->getItems() as $childProduct) { + $formattedChild = $this->formatter->format($childProduct); + $categoryLinks = $this->productResource->getCategoryIds($childProduct); + /** @var Product $item */ + foreach ($childCollection->getItems() as $item) { + if ($childProduct->getId() !== $item->getId()) { + continue; + } + + $parentId = $item->getParentId(); + } + foreach ($categoryLinks as $position => $link) { + $formattedChild['category_links'][] = ['position' => $position, 'category_id' => $link]; + } + if (!isset($this->childrenMap[$parentId])) { + $this->childrenMap[$parentId] = []; + } + + $this->childrenMap[$parentId][] = $formattedChild; + } + + return $this->childrenMap; + } +} diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml b/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml deleted file mode 100644 index 1dae6f2a3d9ba..0000000000000 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product"> - <plugin name="add_configurable_data" type="Magento\ConfigurableProductGraphQl\Model\Plugin\Model\Resolver\Products\DataProvider\ProductPlugin"/> - </type> - <type name="Magento\CatalogGraphQl\Model\Resolver\Products\Query\Filter"> - <arguments> - <argument name="postProcessors" xsi:type="array"> - <item name="configurable_processor" xsi:type="object">Magento\ConfigurableProductGraphQl\Model\Resolver\Products\Query\ConfigurableProductPostProcessor</item> - </argument> - </arguments> - </type> -</config> diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml index 748462cf94772..1bb66233caed0 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml +++ b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml @@ -8,20 +8,33 @@ <implements interface="ProductInterface" copyFields="true"/> <implements interface="PhysicalProductInterface" copyFields="true"/> <implements interface="CustomizableProductInterface" copyFields="true"/> - <field xsi:type="ObjectArrayOutputField" name="configurable_product_links" itemType="SimpleProduct"/> - <field xsi:type="ObjectArrayOutputField" name="configurable_product_options" itemType="ConfigurableProductOptions"/> + <field xsi:type="ObjectArrayOutputField" name="variants" itemType="ConfigurableVariant" resolver="Magento\ConfigurableProductGraphQl\Model\Resolver\ConfigurableVariant" /> + <field xsi:type="ObjectArrayOutputField" name="configurable_options" itemType="ConfigurableProductOptions" resolver="Magento\ConfigurableProductGraphQl\Model\Resolver\Options"/> + </type> + <type xsi:type="OutputType" name="ConfigurableVariant"> + <field xsi:type="ObjectArrayOutputField" name="attributes" itemType="ConfigurableAttributeOption"/> + <field xsi:type="ObjectOutputField" name="product" type="SimpleProduct"/> + </type> + <type xsi:type="OutputType" name="ConfigurableAttributeOption"> + <field xsi:type="ScalarOutputField" name="label" type="String"/> + <field xsi:type="ScalarOutputField" name="code" type="String"/> + <field xsi:type="ScalarOutputField" name="value_index" type="Int"/> </type> <type xsi:type="OutputType" name="ConfigurableProductOptions"> <field xsi:type="ScalarOutputField" name="id" type="Int" description="The configurable option ID number assigned by the system"/> - <field xsi:type="ScalarOutputField" name="attribute_id" type="String" description="The ID assigned to the attribute"/> + <field xsi:type="ScalarOutputField" name="attribute_id" type="Int" description="The ID assigned to the attribute"/> <field xsi:type="ScalarOutputField" name="attribute_code" type="String" description="A string that identifies the attribute"/> <field xsi:type="ScalarOutputField" name="label" type="String" description="A string that describes the configurable product option. It is displayed on the UI."/> <field xsi:type="ScalarOutputField" name="position" type="Int" description="A number that indicates the order in which the attribute is displayed."/> - <field xsi:type="ScalarOutputField" name="is_use_default" type="Boolean" description="Indicates whether the option is the default."/> + <field xsi:type="ScalarOutputField" name="use_default" type="Boolean" description="Indicates whether the option is the default."/> <field xsi:type="ObjectArrayOutputField" name="values" itemType="ConfigurableProductOptionsValues" description="An array that defines the value_index codes assigned to the configurable product."/> <field xsi:type="ScalarOutputField" name="product_id" type="Int" description="This is the same as a product's 'id' field."/> </type> <type xsi:type="OutputType" name="ConfigurableProductOptionsValues"> <field xsi:type="ScalarOutputField" name="value_index" type="Int" description="A unique index number assigned to the configurable product option"/> + <field xsi:type="ScalarOutputField" name="label" type="String"/> + <field xsi:type="ScalarOutputField" name="default_label" type="String"/> + <field xsi:type="ScalarOutputField" name="store_label" type="String"/> + <field xsi:type="ScalarOutputField" name="use_default_value" type="Boolean"/> </type> </config> diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql/di.xml b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql/di.xml index dbbe79930efa2..6cf56d4a45aa0 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql/di.xml @@ -6,13 +6,6 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterComposite"> - <arguments> - <argument name="formatterInstances" xsi:type="array"> - <item name="add_configurable_data" xsi:type="object">Magento\ConfigurableProductGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter\ConfigurableOptions</item> - </argument> - </arguments> - </type> <type name="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> <arguments> <argument name="productTypeNameResolvers" xsi:type="array"> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php index 5f8724a00bbf6..cbea0ebad2eaa 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php @@ -6,6 +6,7 @@ namespace Magento\GraphQl\ConfigurableProduct; +use Magento\Bundle\Model\Product\OptionList; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\ConfigurableProduct\Api\Data\OptionInterface; @@ -27,19 +28,92 @@ public function testQueryConfigurableProductLinks() $query = <<<QUERY { - products(filter: {sku: {eq: "{$productSku}"}}) - { - items{ + products(filter: {sku: {eq: "{$productSku}"}}) { + items { + id + attribute_set_id + created_at + name + sku + type_id + updated_at + ... on PhysicalProductInterface { + weight + } + price { + minimalPrice { + amount { + value + currency + } + adjustments { + amount { + value + currency + } + code + description + } + } + maximalPrice { + amount { + value + currency + } + adjustments { + amount { + value + currency + } + code + description + } + } + regularPrice { + amount { + value + currency + } + adjustments { + amount { + value + currency + } + code + description + } + } + } + category_ids + ... on ConfigurableProduct { + configurable_options { + id + attribute_id + label + position + use_default + attribute_code + values { + value_index + label + store_label + default_label + use_default_value + } + product_id + } + variants { + product { id - attribute_set_id - created_at + category_ids name sku - type_id - updated_at + attribute_set_id ... on PhysicalProductInterface { - weight + weight } + created_at + updated_at price { minimalPrice { amount { @@ -84,106 +158,37 @@ public function testQueryConfigurableProductLinks() } } } - category_ids - ... on ConfigurableProduct { - configurable_product_options{ - id - attribute_id - label - position - is_use_default - values{ - value_index - } - product_id + category_links { + position + category_id + } + media_gallery_entries { + disabled + file + id + label + media_type + position + types + content { + base64_encoded_data + type + name + } + video_content { + media_type + video_description + video_metadata + video_provider + video_title + video_url } - configurable_product_links { - id - category_ids - name - sku - attribute_set_id - ... on PhysicalProductInterface { - weight - } - created_at - updated_at - price { - minimalPrice { - amount { - value - currency - } - adjustments { - amount { - value - currency - } - code - description - } - } - maximalPrice { - amount { - value - currency - } - adjustments { - amount { - value - currency - } - code - description - } - } - regularPrice { - amount { - value - currency - } - adjustments { - amount { - value - currency - } - code - description - } - } - } - category_links { - position - category_id - } - media_gallery_entries { - disabled - file - id - label - media_type - position - types - content - { - base64_encoded_data - type - name - } - video_content - { - media_type - video_description - video_metadata - video_provider - video_title - video_url - } - } - } } + } } + } } + } } QUERY; @@ -201,8 +206,8 @@ public function testQueryConfigurableProductLinks() $this->assertEquals(1, count($response['products']['items'])); $this->assertArrayHasKey(0, $response['products']['items']); $this->assertBaseFields($product, $response['products']['items'][0]); - $this->assertConfigurableProductLinks($response['products']['items'][0]); $this->assertConfigurableProductOptions($response['products']['items'][0]); + $this->assertConfigurableVariants($response['products']['items'][0]); } /** @@ -258,29 +263,28 @@ private function assertBaseFields($product, $actualResponse) * @param $actualResponse * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - private function assertConfigurableProductLinks($actualResponse) + private function assertConfigurableVariants($actualResponse) { $this->assertNotEmpty( - $actualResponse['configurable_product_links'], - "Precondition failed: 'configurable_product_links' must not be empty" + $actualResponse['variants'], + "Precondition failed: 'variants' must not be empty" ); - foreach ($actualResponse[ - 'configurable_product_links' - ] as $configurableProductLinkIndex => $configurableProductLinkArray) { - $this->assertNotEmpty($configurableProductLinkArray); + foreach ($actualResponse['variants'] as $variantKey => $variantArray) { + $this->assertNotEmpty($variantArray); + $this->assertNotEmpty($variantArray['product']); $this->assertTrue( - isset($configurableProductLinkArray['id']), - 'configurable_product_links elements don\'t contain id key' + isset($variantArray['product']['id']), + 'variant product elements don\'t contain id key' ); - $indexValue = $configurableProductLinkArray['id']; - unset($configurableProductLinkArray['id']); + $indexValue = $variantArray['product']['id']; + unset($variantArray['product']['id']); $this->assertTrue( - isset($configurableProductLinkArray['category_ids']), - 'configurable_product_links doesn\'t contain category_ids key' + isset($variantArray['product']['category_ids']), + 'variant product doesn\'t contain category_ids key' ); $this->assertTrue( - isset($configurableProductLinkArray['category_links']), - 'configurable_product_links doesn\'t contain category_links key' + isset($variantArray['product']['category_links']), + 'variant product doesn\'t contain category_links key' ); $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); /** @var \Magento\Catalog\Model\Product $childProduct */ @@ -293,15 +297,15 @@ private function assertConfigurableProductLinks($actualResponse) $categoryId = $links[0]->getCategoryId(); $actualValue - = $actualResponse['configurable_product_links'][$configurableProductLinkIndex]['category_links'][0]; - $this->assertEquals($actualValue, ['position' => $position, 'category_id' =>$categoryId]); - unset($configurableProductLinkArray['category_links']); + = $actualResponse['variants'][$variantKey]['product']['category_links'][0]; + $this->assertEquals($actualValue, ['position' => $position, 'category_id' => $categoryId]); + unset($variantArray['product']['category_links']); $categoryIdsAttribute = $childProduct->getCustomAttribute('category_ids'); $this->assertNotEmpty($categoryIdsAttribute, "Precondition failed: 'category_ids' must not be empty"); $categoryIdsAttributeValue = $categoryIdsAttribute ? $categoryIdsAttribute->getValue() : []; - $this->assertEquals($categoryIdsAttributeValue, $actualResponse['category_ids']); - unset($configurableProductLinkArray['category_ids']); + $this->assertEquals($categoryIdsAttributeValue, $variantArray['product']['category_ids']); + unset($variantArray['product']['category_ids']); $mediaGalleryEntries = $childProduct->getMediaGalleryEntries(); $this->assertCount( @@ -311,20 +315,22 @@ private function assertConfigurableProductLinks($actualResponse) ); $this->assertTrue( is_array( - $actualResponse['configurable_product_links'] - [$configurableProductLinkIndex] + $actualResponse['variants'] + [$variantKey] + ['product'] ['media_gallery_entries'] ) ); $this->assertCount( 1, - $actualResponse['configurable_product_links'][$configurableProductLinkIndex]['media_gallery_entries'], + $actualResponse['variants'][$variantKey]['product']['media_gallery_entries'], "there must be 1 record in the media gallery" ); $mediaGalleryEntry = $mediaGalleryEntries[0]; $this->assertResponseFields( - $actualResponse['configurable_product_links'] - [$configurableProductLinkIndex] + $actualResponse['variants'] + [$variantKey] + ['product'] ['media_gallery_entries'][0], [ 'disabled' => (bool)$mediaGalleryEntry->isDisabled(), @@ -337,8 +343,9 @@ private function assertConfigurableProductLinks($actualResponse) ); $videoContent = $mediaGalleryEntry->getExtensionAttributes()->getVideoContent(); $this->assertResponseFields( - $actualResponse['configurable_product_links'] - [$configurableProductLinkIndex] + $actualResponse['variants'] + [$variantKey] + ['product'] ['media_gallery_entries'] [0] ['video_content'], @@ -351,9 +358,9 @@ private function assertConfigurableProductLinks($actualResponse) 'video_url' => $videoContent->getVideoUrl() ] ); - unset($configurableProductLinkArray['media_gallery_entries']); + unset($variantArray['product']['media_gallery_entries']); - foreach ($configurableProductLinkArray as $key => $value) { + foreach ($variantArray['product'] as $key => $value) { if ($key !== 'price') { $this->assertEquals($value, $childProduct->getData($key)); } @@ -383,7 +390,7 @@ private function assertConfigurableProductLinks($actualResponse) 'adjustments' => [] ], ], - $configurableProductLinkArray['price'] + $variantArray['product']['price'] ); } } @@ -391,45 +398,67 @@ private function assertConfigurableProductLinks($actualResponse) private function assertConfigurableProductOptions($actualResponse) { $this->assertNotEmpty( - $actualResponse['configurable_product_options'], + $actualResponse['configurable_options'], "Precondition failed: 'configurable_product_options' must not be empty" ); $productSku = 'configurable'; - /** @var OptionRepositoryInterface $optionRepository */ - $optionRepository = ObjectManager::getInstance()->get(OptionRepositoryInterface::class); - $configurableAttributeOptions = $optionRepository->getList($productSku); - $configurableAttributeOption = $configurableAttributeOptions[0]; - /** @var Attribute $attribute */ - //$attribute = ObjectManager::getInstance()->get(Attribute::class); - /** @var OptionInterface $option */ - $option = ObjectManager::getInstance()->get(OptionInterface::class); + /** @var ProductRepositoryInterface $productRepo */ + $productRepo = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); + $product = $productRepo->get($productSku); + $configurableAttributeOptions = $product->getExtensionAttributes()->getConfigurableProductOptions(); + foreach ($configurableAttributeOptions as $option) { + $configurableAttributeOption = $option->getData(); + $configurableAttributeOption['id'] = $option->getId(); + $configurableAttributeOption['attribute_code'] = $option->getProductAttribute()->getAttributeCode(); + break; + } - // TODO: uncomment the assertions once issue MAGETWO-88216 is fixed. - //$this->assertEquals($actualResponse['configurable_product_options'][0]['id'], $configurableAttributeOption->getId()); - // $this->assertEquals($actualResponse['configurable_product_options'][0]['is_use_default'], (bool)$attribute->getIsUseDefault()); $this->assertEquals( - $actualResponse['configurable_product_options'][0]['attribute_id'], - $configurableAttributeOption->getAttributeId() + $actualResponse['configurable_options'][0]['id'], + $configurableAttributeOption['id'] + ); + $this->assertEquals( + $actualResponse['configurable_options'][0]['use_default'], + (bool)$configurableAttributeOption['use_default'] + ); + $this->assertEquals( + $actualResponse['configurable_options'][0]['attribute_id'], + $configurableAttributeOption['attribute_id'] + ); + $this->assertEquals( + $actualResponse['configurable_options'][0]['label'], + $configurableAttributeOption['label'] ); $this->assertEquals( - $actualResponse['configurable_product_options'][0]['label'], - $configurableAttributeOption->getLabel() + $actualResponse['configurable_options'][0]['position'], + $configurableAttributeOption['position'] ); $this->assertEquals( - $actualResponse['configurable_product_options'][0]['position'], - $configurableAttributeOption->getPosition() + $actualResponse['configurable_options'][0]['product_id'], + $configurableAttributeOption['product_id'] ); $this->assertEquals( - $actualResponse['configurable_product_options'][0]['product_id'], - $configurableAttributeOption->getProductId() + $actualResponse['configurable_options'][0]['attribute_code'], + $configurableAttributeOption['attribute_code'] ); - // $this->assertEquals($actualResponse['configurable_product_options'][0]['is_use_default'], $option->getIsUseDefault()); - /*foreach ($actualResponse['configurable_product_options'][0]['values'] as $value) { + foreach ($actualResponse['configurable_options'][0]['values'] as $key => $value) { + $this->assertEquals( + $value['label'], + $configurableAttributeOption['options'][$key]['label'] + ); + $this->assertEquals( + $value['store_label'], + $configurableAttributeOption['options'][$key]['store_label'] + ); + $this->assertEquals( + $value['default_label'], + $configurableAttributeOption['options'][$key]['default_label'] + ); $this->assertEquals( - $actualResponse ['configurable_product_options'][0]['values'][$value]['value_index'], - $configurableAttributeOption->getOptions()[$value]['value_index'] + $value['use_default_value'], + $configurableAttributeOption['options'][$key]['use_default_value'] ); - }*/ + } } /** From 4422441c9f7d3cf88ad99cb00da21665ea1c638a Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@magento.com> Date: Tue, 20 Mar 2018 10:31:07 -0500 Subject: [PATCH 117/668] MAGETWO-89366: Create integration or api tests - Added description at type level --- .../testsuite/Magento/GraphQl/GraphQlIntrospectionTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/GraphQlIntrospectionTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/GraphQlIntrospectionTest.php index a4cdcd913481c..c605bd583f863 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQl/GraphQlIntrospectionTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQl/GraphQlIntrospectionTest.php @@ -33,6 +33,7 @@ public function testIntrospectionQuery() 'query' => new ObjectType( [ 'name' => 'Query', + 'description' =>'Description at type level', 'fields' => ['a' => Type::string()] ] ) @@ -50,6 +51,7 @@ public function testIntrospectionQuery() } fragment FullType on __Type{ name +description kind fields(includeDeprecated:true){ name @@ -81,6 +83,7 @@ public function testIntrospectionQuery() $expectedFragment = [ 'name' => 'Query', + 'description' => 'Description at type level', 'kind' => 'OBJECT', 'fields' => [ [ From dd493bd41eb3a589e264239a755bb6fbabbaedb6 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 20 Mar 2018 11:13:55 -0500 Subject: [PATCH 118/668] MAGETWO-89260: Fix Travis build issues --- app/code/Magento/Backend/Block/Menu.php | 9 +++++++-- app/code/Magento/Theme/Block/Html/Topmenu.php | 4 ++-- .../Magento/Framework/Session/ConfigTest.php | 16 ++++++---------- .../Framework/Session/SaveHandlerTest.php | 5 +---- .../Framework/Session/SessionManagerTest.php | 3 +++ .../Framework/Session/SidResolverTest.php | 2 ++ .../Framework/Encryption/Test/Unit/CryptTest.php | 6 ++++-- lib/internal/Magento/Framework/File/Uploader.php | 4 ++-- .../Fixtures/ConfigurableProductsFixture.php | 7 ++++--- .../Model/FixtureGenerator/ProductGenerator.php | 6 ++---- 10 files changed, 33 insertions(+), 29 deletions(-) diff --git a/app/code/Magento/Backend/Block/Menu.php b/app/code/Magento/Backend/Block/Menu.php index d6bdeb4ea8968..e19b3769ac981 100644 --- a/app/code/Magento/Backend/Block/Menu.php +++ b/app/code/Magento/Backend/Block/Menu.php @@ -387,7 +387,12 @@ public function renderNavigation($menu, $level = 0, $limit = 0, $colBrakes = []) $itemName = substr($menuId, strrpos($menuId, '::') + 2); $itemClass = str_replace('_', '-', strtolower($itemName)); - if (count($colBrakes) && $colBrakes[$itemPosition]['colbrake'] && $itemPosition != 1) { + if ( + is_array($colBrakes) + && count($colBrakes) + && $colBrakes[$itemPosition]['colbrake'] + && $itemPosition != 1 + ) { $output .= '</ul></li><li class="column"><ul role="menu">'; } @@ -401,7 +406,7 @@ public function renderNavigation($menu, $level = 0, $limit = 0, $colBrakes = []) $itemPosition++; } - if (count($colBrakes) && $limit) { + if (is_array($colBrakes) && count($colBrakes) && $limit) { $output = '<li class="column"><ul role="menu">' . $output . '</ul></li>'; } diff --git a/app/code/Magento/Theme/Block/Html/Topmenu.php b/app/code/Magento/Theme/Block/Html/Topmenu.php index 6c5ca39c61831..0aaaf34a05922 100644 --- a/app/code/Magento/Theme/Block/Html/Topmenu.php +++ b/app/code/Magento/Theme/Block/Html/Topmenu.php @@ -244,7 +244,7 @@ protected function _getHtml( } } - if (count($colBrakes) && $colBrakes[$counter]['colbrake']) { + if (is_array($colBrakes) && count($colBrakes) && $colBrakes[$counter]['colbrake']) { $html .= '</ul></li><li class="column"><ul>'; } @@ -261,7 +261,7 @@ protected function _getHtml( $counter++; } - if (count($colBrakes) && $limit) { + if (is_array($colBrakes) && count($colBrakes) && $limit) { $html = '<li class="column"><ul>' . $html . '</ul></li>'; } diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php index 573531cff960a..3e7f989ca39f7 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php @@ -13,28 +13,24 @@ class ConfigTest extends \PHPUnit\Framework\TestCase { /** @var \Magento\Framework\Session\Config */ - protected $_model; + private $_model; /** @var string */ - protected $_cacheLimiter = 'private_no_expire'; + private $_cacheLimiter = 'private_no_expire'; /** @var \Magento\TestFramework\ObjectManager */ - protected $_objectManager; + private $_objectManager; /** @var string Default value for session.save_path setting */ - protected $defaultSavePath; + private $defaultSavePath; /** @var \Magento\Framework\App\DeploymentConfig | \PHPUnit_Framework_MockObject_MockObject */ - protected $deploymentConfigMock; + private $deploymentConfigMock; protected function setUp() { $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - /** @var $sessionManager \Magento\Framework\Session\SessionManager */ - $sessionManager = $this->_objectManager->create(\Magento\Framework\Session\SessionManager::class); - if ($sessionManager->isSessionExists()) { - $sessionManager->writeClose(); - } + $this->deploymentConfigMock = $this->createMock(\Magento\Framework\App\DeploymentConfig::class); $this->deploymentConfigMock ->method('get') diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php index 81630b1827037..690ae05d75988 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php @@ -55,11 +55,8 @@ public function testSetSaveHandler($deploymentConfigHandler, $iniHandler) $expected, ObjectManager::getInstance()->get(ConfigInterface::class)->getOption('session.save_handler') ); - } - public function tearDown() - { - if (isset($this->originalSaveHandler)) { + if ($iniHandler && isset($this->originalSaveHandler) && $iniHandler != $this->originalSaveHandler) { ini_set('session.save_handler', $this->originalSaveHandler); } } diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php index 1cfe77b22a69b..fbada0f0dca36 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php @@ -114,6 +114,7 @@ protected function tearDown() { global $mockPHPFunctions; $mockPHPFunctions = false; + $this->_model->destroy(); } public function testSessionNameFromIni() @@ -149,7 +150,9 @@ public function testGetName() public function testSetName() { + $this->_model->destroy(); $this->_model->setName('test'); + $this->_model->start(); $this->assertEquals('test', $this->_model->getName()); } diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php index 6e043728b073a..e928422528409 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php @@ -154,10 +154,12 @@ public function testGetSessionIdQueryParam() public function testGetSessionIdQueryParamCustom() { + $this->session->destroy(); $oldSessionName = $this->session->getName(); $this->session->setName($this->customSessionName); $this->assertEquals($this->customSessionQueryParam, $this->model->getSessionIdQueryParam($this->session)); $this->session->setName($oldSessionName); + $this->session->start(); } public function testSetGetUseSessionVar() diff --git a/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php b/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php index 55a078aaade7d..ac99bbc7a00a7 100644 --- a/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php +++ b/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php @@ -111,8 +111,10 @@ public function getConstructorExceptionData() $tooShortInitVector = str_repeat('-', $this->_getInitVectorSize($cipher, $mode) - 1); $tooLongInitVector = str_repeat('-', $this->_getInitVectorSize($cipher, $mode) + 1); $result['tooLongKey-' . $cipher . '-' . $mode . '-false'] = [$tooLongKey, $cipher, $mode, false]; - $result['key-' . $cipher . '-' . $mode . '-tooShortInitVector'] = [$this->_key, $cipher, $mode, $tooShortInitVector]; - $result['key-' . $cipher . '-' . $mode . '-tooLongInitVector'] = [$this->_key, $cipher, $mode, $tooLongInitVector]; + $result['key-' . $cipher . '-' . $mode . '-tooShortInitVector'] + = [$this->_key, $cipher, $mode, $tooShortInitVector]; + $result['key-' . $cipher . '-' . $mode . '-tooLongInitVector'] + = [$this->_key, $cipher, $mode, $tooLongInitVector]; } } return $result; diff --git a/lib/internal/Magento/Framework/File/Uploader.php b/lib/internal/Magento/Framework/File/Uploader.php index 07de9941271c3..67d7d4bb558ae 100644 --- a/lib/internal/Magento/Framework/File/Uploader.php +++ b/lib/internal/Magento/Framework/File/Uploader.php @@ -534,7 +534,7 @@ private function _setUploadFileId($fileId) preg_match("/^(.*?)\[(.*?)\]$/", $fileId, $file); - if (count($file) > 0 && count($file[0]) > 0 && count($file[1]) > 0) { + if (is_array($file) && count($file) > 0 && count($file[0]) > 0 && count($file[1]) > 0) { array_shift($file); $this->_uploadType = self::MULTIPLE_STYLE; @@ -547,7 +547,7 @@ private function _setUploadFileId($fileId) $fileAttributes = $tmpVar; $this->_file = $fileAttributes; - } elseif (count($fileId) > 0 && isset($_FILES[$fileId])) { + } elseif (!empty($fileId) && isset($_FILES[$fileId])) { $this->_uploadType = self::SINGLE_STYLE; $this->_file = $_FILES[$fileId]; } elseif ($fileId == '') { diff --git a/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php b/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php index d87a058a0363d..00c60a2a8a6a5 100644 --- a/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php +++ b/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php @@ -847,10 +847,11 @@ private function getDescriptionClosure( $minAmountOfWordsDescription, $descriptionPrefix ) { + $countSearchTerms = is_array($searchTerms) ? count($searchTerms) : 0; $count = !$searchTerms ? 0 : round( - $searchTerms[$index % count($searchTerms)]['count'] * ( + $searchTerms[$index % $countSearchTerms]['count'] * ( $configurableProductsCount / ($simpleProductsCount + $configurableProductsCount) ) ); @@ -860,8 +861,8 @@ private function getDescriptionClosure( $maxAmountOfWordsDescription, $descriptionPrefix . '-' . $index ) . - ($index <= ($count * count($searchTerms)) ? ' ' . - $searchTerms[$index % count($searchTerms)]['term'] : ''); + ($index <= ($count * $countSearchTerms) ? ' ' . + $searchTerms[$index % $countSearchTerms]['term'] : ''); }; } diff --git a/setup/src/Magento/Setup/Model/FixtureGenerator/ProductGenerator.php b/setup/src/Magento/Setup/Model/FixtureGenerator/ProductGenerator.php index 24813302133e1..b642f553dae74 100644 --- a/setup/src/Magento/Setup/Model/FixtureGenerator/ProductGenerator.php +++ b/setup/src/Magento/Setup/Model/FixtureGenerator/ProductGenerator.php @@ -170,10 +170,8 @@ public function generate($products, $fixtureMap) ], ], ]; - if ( - !is_array($fixtureMap['website_ids'](1, 0)) || - count($fixtureMap['website_ids'](1, 0)) === 1 - ) { + $websiteIdsFixtures = $fixtureMap['website_ids'](1, 0); + if ((is_array($websiteIdsFixtures) && count($websiteIdsFixtures) === 1) || !is_null($websiteIdsFixtures)) { // Get website id from fixture in case when one site is assigned per product $customTableMap['catalog_product_website'] = [ 'fields' => [ From 7d9c389074631bbc63a1df6c20b9e3db6d07916e Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Tue, 20 Mar 2018 11:18:06 -0500 Subject: [PATCH 119/668] MAGETWO-87655: Add attributes to variant assertion. --- .../ConfigurableProductViewTest.php | 75 +++++++++++++++---- 1 file changed, 60 insertions(+), 15 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php index cbea0ebad2eaa..a2b3a02e21024 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php @@ -6,17 +6,18 @@ namespace Magento\GraphQl\ConfigurableProduct; -use Magento\Bundle\Model\Product\OptionList; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\ConfigurableProduct\Api\Data\OptionInterface; -use Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute; use Magento\TestFramework\ObjectManager; -use Magento\ConfigurableProduct\Api\OptionRepositoryInterface; use Magento\TestFramework\TestCase\GraphQlAbstract; class ConfigurableProductViewTest extends GraphQlAbstract { + /** + * @var array + */ + private $configurableOptions = []; + /** * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable_with_category_and_weight.php * @SuppressWarnings(PHPMD.ExcessiveMethodLength) @@ -185,6 +186,11 @@ public function testQueryConfigurableProductLinks() } } } + attributes { + label + code + value_index + } } } } @@ -392,6 +398,23 @@ private function assertConfigurableVariants($actualResponse) ], $variantArray['product']['price'] ); + $configurableOptions = $this->getConfigurableOptions(); + foreach ($variantArray['attributes'] as $attribute) { + $hasAssertion = false; + foreach ($configurableOptions as $option) { + foreach ($option['options'] as $value) { + if ((int)$value['value_index'] === (int)$attribute['value_index']) { + $this->assertEquals((int)$attribute['value_index'], (int)$value['value_index']); + $this->assertEquals($attribute['label'], $value['label']); + $hasAssertion = true; + } + } + $this->assertEquals($attribute['code'], $option['attribute_code']); + } + if (!$hasAssertion) { + $this->fail('variant did not contain correct attributes'); + } + } } } @@ -401,17 +424,8 @@ private function assertConfigurableProductOptions($actualResponse) $actualResponse['configurable_options'], "Precondition failed: 'configurable_product_options' must not be empty" ); - $productSku = 'configurable'; - /** @var ProductRepositoryInterface $productRepo */ - $productRepo = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); - $product = $productRepo->get($productSku); - $configurableAttributeOptions = $product->getExtensionAttributes()->getConfigurableProductOptions(); - foreach ($configurableAttributeOptions as $option) { - $configurableAttributeOption = $option->getData(); - $configurableAttributeOption['id'] = $option->getId(); - $configurableAttributeOption['attribute_code'] = $option->getProductAttribute()->getAttributeCode(); - break; - } + $configurableAttributeOptions = $this->getConfigurableOptions(); + $configurableAttributeOption = array_shift($configurableAttributeOptions); $this->assertEquals( $actualResponse['configurable_options'][0]['id'], @@ -458,6 +472,10 @@ private function assertConfigurableProductOptions($actualResponse) $value['use_default_value'], $configurableAttributeOption['options'][$key]['use_default_value'] ); + $this->assertEquals( + (int)$value['value_index'], + (int)$configurableAttributeOption['options'][$key]['value_index'] + ); } } @@ -485,4 +503,31 @@ private function assertResponseFields(array $actualResponse, array $assertionMap ); } } + + private function getConfigurableOptions() + { + if (!empty($this->configurableOptions)) { + return $this->configurableOptions; + } + $productSku = 'configurable'; + /** @var ProductRepositoryInterface $productRepo */ + $productRepo = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); + $product = $productRepo->get($productSku); + $configurableAttributeOptions = $product->getExtensionAttributes()->getConfigurableProductOptions(); + $configurableAttributeOptionsData = []; + foreach ($configurableAttributeOptions as $option) { + $configurableAttributeOptionsData[$option->getId()] = $option->getData(); + $configurableAttributeOptionsData[$option->getId()]['id'] = $option->getId(); + $configurableAttributeOptionsData[$option->getId()]['attribute_code'] + = $option->getProductAttribute()->getAttributeCode(); + unset($configurableAttributeOptionsData[$option->getId()]['values']); + foreach ($option->getValues() as $value) { + $configurableAttributeOptionsData[$option->getId()]['values'][$value->getId()] = $value->getData(); + $configurableAttributeOptionsData[$option->getId()]['values'][$value->getId()]['label'] + = $value->getLabel(); + } + } + + return $this->configurableOptions = $configurableAttributeOptionsData; + } } From 3336c45569ebb25c47cd1e34505352882ddc61c7 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 20 Mar 2018 11:52:52 -0500 Subject: [PATCH 120/668] MAGETWO-89260: Fix Travis build issues - fix static test failure --- app/code/Magento/Backend/Block/Menu.php | 3 +-- .../Magento/Setup/Model/FixtureGenerator/ProductGenerator.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Backend/Block/Menu.php b/app/code/Magento/Backend/Block/Menu.php index e19b3769ac981..717edb8fe06fc 100644 --- a/app/code/Magento/Backend/Block/Menu.php +++ b/app/code/Magento/Backend/Block/Menu.php @@ -387,8 +387,7 @@ public function renderNavigation($menu, $level = 0, $limit = 0, $colBrakes = []) $itemName = substr($menuId, strrpos($menuId, '::') + 2); $itemClass = str_replace('_', '-', strtolower($itemName)); - if ( - is_array($colBrakes) + if (is_array($colBrakes) && count($colBrakes) && $colBrakes[$itemPosition]['colbrake'] && $itemPosition != 1 diff --git a/setup/src/Magento/Setup/Model/FixtureGenerator/ProductGenerator.php b/setup/src/Magento/Setup/Model/FixtureGenerator/ProductGenerator.php index b642f553dae74..b8c15f09faf7a 100644 --- a/setup/src/Magento/Setup/Model/FixtureGenerator/ProductGenerator.php +++ b/setup/src/Magento/Setup/Model/FixtureGenerator/ProductGenerator.php @@ -171,7 +171,7 @@ public function generate($products, $fixtureMap) ], ]; $websiteIdsFixtures = $fixtureMap['website_ids'](1, 0); - if ((is_array($websiteIdsFixtures) && count($websiteIdsFixtures) === 1) || !is_null($websiteIdsFixtures)) { + if ((is_array($websiteIdsFixtures) && count($websiteIdsFixtures) === 1) || $websiteIdsFixtures != null) { // Get website id from fixture in case when one site is assigned per product $customTableMap['catalog_product_website'] = [ 'fields' => [ From e66511a597581009395138f328186b86a780e16b Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 20 Mar 2018 13:07:49 -0500 Subject: [PATCH 121/668] MAGETWO-89260: Fix Travis build issues - fix integrity test failure --- .../Test/Integrity/Magento/Backend/ControllerAclTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php index 175a9aadbeaec..5e1cfa1106d7e 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php @@ -233,7 +233,7 @@ private function isItTest($relativeFilePath) private function getControllerPath($relativeFilePath) { if (preg_match('~(Magento\/.*Controller\/Adminhtml\/.*)\.php~', $relativeFilePath, $matches)) { - if (count($matches) === 2 && count($partPath = $matches[1]) >= 1) { + if (is_array($matches) && count($matches) === 2 && is_array($matches[1]) && count($matches[1]) >= 1) { $partPath = $matches[1]; return $partPath; } From 91c0e73cebeba60382194bf084b41a4d35828996 Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" <a.vasiliev@sam-solutions.biz> Date: Tue, 20 Mar 2018 21:14:09 +0200 Subject: [PATCH 122/668] fix counting different operations statuses in bulkStatus --- .../Model/BulkStatus.php | 28 ++++--------------- .../Model/Operation/Details.php | 7 +---- 2 files changed, 6 insertions(+), 29 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php b/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php index 3134b80165652..a0e8464641ea9 100644 --- a/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php +++ b/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php @@ -153,24 +153,6 @@ public function getFailedOperationsByBulkId($bulkUuid, $failureType = null) */ public function getOperationsCountByBulkIdAndStatus($bulkUuid, $status) { - if ($status === OperationInterface::STATUS_TYPE_OPEN) { - /** - * Total number of operations that has been scheduled within the given bulk - */ - $allOperationsQty = $this->getOperationCount($bulkUuid); - - /** - * Number of operations that has been processed (i.e. operations with any status but 'open') - */ - $allProcessedOperationsQty = (int)$this->operationCollectionFactory->create() - ->addFieldToFilter( - 'bulk_uuid', - $bulkUuid - ) - ->getSize(); - - return $allOperationsQty - $allProcessedOperationsQty; - } /** @var \Magento\AsynchronousOperations\Model\ResourceModel\Operation\Collection $collection */ $collection = $this->operationCollectionFactory->create(); @@ -295,12 +277,12 @@ public function getBulkDetails($bulkUuid) /** @var \Magento\AsynchronousOperations\Model\Operation\Details $operationDetails */ $operationDetails = $this->operationDetailsFactory->create(['bulkUuid' => $bulkUuid]); - /** @var \Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterface $bulkExtensionAttribute */ - $bulkExtensionAttribute = $this->bulkSummaryExtensionInterfaceFactory->create(); - $bulkExtensionAttribute->setOperationsList($operationList); + /** @var \Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterface $bulkAttribute */ + $bulkAttribute = $this->bulkSummaryExtensionInterfaceFactory->create(); + $bulkAttribute->setOperationsList($operationList); - $bulkExtensionAttribute->setOperationsCount($operationDetails); - $bulk->setExtensionAttributes($bulkExtensionAttribute); + $bulkAttribute->setOperationsCount($operationDetails); + $bulk->setExtensionAttributes($bulkAttribute); return $bulk; } diff --git a/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php b/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php index 2faa4e32abf95..05ea2de09f868 100644 --- a/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php +++ b/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php @@ -78,12 +78,7 @@ public function getDetails($bulkUuid) ); } - // total is sum of successful, rejected, retriable, not retriable and open operations - $details['operations_total'] = - array_sum($details) + $this->bulkStatus->getOperationsCountByBulkIdAndStatus( - $bulkUuid, - OperationInterface::STATUS_TYPE_OPEN - ); + $details['operations_total'] = array_sum($details); $details['operations_failed'] = $details['failed_retriable'] + $details['failed_not_retriable']; $this->operationCache[$bulkUuid] = $details; From b2f3c84293523971f38df442403986dc38fa480c Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 20 Mar 2018 14:22:25 -0500 Subject: [PATCH 123/668] MAGETWO-89260: Fix Travis build issues - fix test framework unit test --- .../unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php index b6207f309ead9..9bd4ef6bf37a7 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php @@ -9,6 +9,7 @@ */ namespace Magento\Test\Bootstrap; +ob_start(); class EnvironmentTest extends \PHPUnit\Framework\TestCase { /** @@ -76,4 +77,4 @@ public function testEmulateSession() $this->assertSame($sessionVars, $this->_getSessionVars(), 'Super-global $_SESSION must not be affected.'); $this->assertNotEmpty(session_id(), 'Global session identified has to be emulated.'); } -} +} \ No newline at end of file From 716bf057834f6723892f504c4963eb5cbd432a18 Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Tue, 20 Mar 2018 15:23:57 -0500 Subject: [PATCH 124/668] magento-engcom/bulk-api#4 Support for Async operations in WebAPI - get AsynchronousRequestProcessor implement ProcessorInterface - remove exception hiding --- .../Config/RemoteServiceReader/Communication.php | 6 +----- .../Generator/Config/RemoteServiceReader/Consumer.php | 6 +----- .../Generator/Config/RemoteServiceReader/Publisher.php | 7 +------ .../Generator/Config/RemoteServiceReader/Topology.php | 9 ++------- .../Controller/Rest/AsynchronousRequestProcessor.php | 10 ++++++++++ 5 files changed, 15 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php index f2a54d8fd2388..1567e24a429d9 100644 --- a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php @@ -48,11 +48,7 @@ public function __construct( */ public function read($scope = null) { - try { - $asyncServicesData = $this->webapiAsyncConfig->getServices(); - } catch (\Exception $e) { - return []; - } + $asyncServicesData = $this->webapiAsyncConfig->getServices(); $result = []; foreach ($asyncServicesData as $serviceData) { $topicName = $serviceData[WebApiAsyncConfig::SERVICE_PARAM_KEY_TOPIC]; diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php index 4b6c9c4c2dea7..a34d90195477d 100644 --- a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php @@ -37,11 +37,7 @@ public function __construct( */ public function read($scope = null) { - try { - $asyncServicesData = $this->webapiAsyncConfig->getServices(); - } catch (\Exception $e) { - return []; - } + $asyncServicesData = $this->webapiAsyncConfig->getServices(); $result = []; foreach ($asyncServicesData as $serviceData) { $topicName = $serviceData[WebApiAsyncConfig::SERVICE_PARAM_KEY_TOPIC]; diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php index 3a04c0a2e6149..13808bbbf1761 100644 --- a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php @@ -38,15 +38,10 @@ public function __construct( */ public function read($scope = null) { - try { - $asyncServicesData = $this->webapiAsyncConfig->getServices(); - } catch (\Exception $e) { - return []; - } + $asyncServicesData = $this->webapiAsyncConfig->getServices(); $result = []; foreach ($asyncServicesData as $serviceData) { $topicName = $serviceData[WebApiAsyncConfig::SERVICE_PARAM_KEY_TOPIC]; - $result[$topicName] = [ 'topic' => $topicName, diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php index 7e998cb97e215..917dd2ddeb74a 100644 --- a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php @@ -46,12 +46,7 @@ public function __construct( */ public function read($scope = null) { - try { - $asyncServicesData = $this->webapiAsyncConfig->getServices(); - } catch (\Exception $e) { - return []; - } - + $asyncServicesData = $this->webapiAsyncConfig->getServices(); $bindings = []; foreach ($asyncServicesData as $serviceData) { $topicName = $serviceData[WebApiAsyncConfig::SERVICE_PARAM_KEY_TOPIC]; @@ -66,7 +61,7 @@ public function read($scope = null) } $result = [ - 'magento-async--amqp' => + 'magento-async-amqp' => [ 'name' => 'magento', 'type' => 'topic', diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php index ff39ea3f3ed55..c16b69a6fe9fe 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php @@ -122,4 +122,14 @@ private function getTopicName($request) $request->getHttpMethod() ); } + + /** + * {@inheritdoc} + */ + public function canProcess(\Magento\Framework\Webapi\Rest\Request $request) { + if (strpos(ltrim($request->getPathInfo(), '/'), $this->getProcessorPath()) === 0) { + return true; + } + return false; + } } From 1155b291b20d3705eb38cf93d30ccb843799ad74 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <okopylova@magento.com> Date: Tue, 20 Mar 2018 15:33:53 -0500 Subject: [PATCH 125/668] MAGETWO-89235: Update zend-view, zend-mvc and credis libs in EE - updated version on zend-mvc to correspond to Magento 2.2 --- composer.json | 2 +- composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index c09f679cadaf2..0fa33f0f12b1c 100644 --- a/composer.json +++ b/composer.json @@ -66,7 +66,7 @@ "zendframework/zend-log": "^2.9.1", "zendframework/zend-mail": "^2.8.0", "zendframework/zend-modulemanager": "^2.7", - "zendframework/zend-mvc": "~2.7.0", + "zendframework/zend-mvc": "~2.7.12", "zendframework/zend-serializer": "^2.7.2", "zendframework/zend-server": "^2.6.1", "zendframework/zend-servicemanager": "^2.7.8", diff --git a/composer.lock b/composer.lock index 40a27c656d000..d4b29fe2f7f40 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "13dfea4160f301d205183f0d920bbaf0", + "content-hash": "95ad9c4b31ef1192095279c6f66885bf", "packages": [ { "name": "braintree/braintree_php", From df2b36a96e4bf07e311e33922bcf39cecfab9703 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Tue, 20 Mar 2018 16:57:27 -0500 Subject: [PATCH 126/668] MAGETWO-89082: Update composer dependencies -update amqp dependency version --- composer.json | 8 ++++---- composer.lock | 41 +++++++++++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/composer.json b/composer.json index a2ae0aa884d16..1451c694fa7b6 100644 --- a/composer.json +++ b/composer.json @@ -41,14 +41,15 @@ "colinmollenhour/credis": "1.6", "colinmollenhour/php-redis-session-abstract": "~1.3.8", "composer/composer": "~1.6.0", - "magento/composer": "1.3.0.x-dev", "elasticsearch/elasticsearch": "~2.0|~5.1", + "magento/composer": "1.3.0.x-dev", "magento/magento-composer-installer": ">=0.1.11", "magento/zendframework1": "dev-master", "monolog/monolog": "^1.17", "oyejorge/less.php": "~1.7.0", "pelago/emogrifier": "^2.0.0", - "php-amqplib/php-amqplib": "2.5.*", + "php-amqplib/php-amqplib": "~2.7.0", + "phpseclib/mcrypt_compat": "1.0.4", "phpseclib/phpseclib": "2.0.*", "ramsey/uuid": "3.6.1", "symfony/console": "~4.0.0", @@ -83,8 +84,7 @@ "zendframework/zend-text": "^2.6.0", "zendframework/zend-uri": "^2.5.1", "zendframework/zend-validator": "^2.6.0", - "zendframework/zend-view": "^2.8.1", - "phpseclib/mcrypt_compat": "1.0.4" + "zendframework/zend-view": "^2.8.1" }, "require-dev": { "friendsofphp/php-cs-fixer": "~2.10.0", diff --git a/composer.lock b/composer.lock index 90b65ae7afaf8..cc56a7ebd8718 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "8fc58d18fea32a6f01c1aad19133a95d", + "content-hash": "20ac7ba71a76d50eb8dda8d1f824195f", "packages": [ { "name": "braintree/braintree_php", @@ -1138,16 +1138,16 @@ }, { "name": "php-amqplib/php-amqplib", - "version": "v2.5.2", + "version": "v2.7.2", "source": { "type": "git", "url": "https://github.com/php-amqplib/php-amqplib.git", - "reference": "eb8f94d97c8e79900accf77343dbd7eca7f58506" + "reference": "dfd3694a86f1a7394d3693485259d4074a6ec79b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/eb8f94d97c8e79900accf77343dbd7eca7f58506", - "reference": "eb8f94d97c8e79900accf77343dbd7eca7f58506", + "url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/dfd3694a86f1a7394d3693485259d4074a6ec79b", + "reference": "dfd3694a86f1a7394d3693485259d4074a6ec79b", "shasum": "" }, "require": { @@ -1155,8 +1155,14 @@ "ext-mbstring": "*", "php": ">=5.3.0" }, + "replace": { + "videlalvaro/php-amqplib": "self.version" + }, "require-dev": { - "phpunit/phpunit": "3.7.*" + "phpdocumentor/phpdocumentor": "^2.9", + "phpunit/phpunit": "^4.8", + "scrutinizer/ocular": "^1.1", + "squizlabs/php_codesniffer": "^2.5" }, "suggest": { "ext-sockets": "Use AMQPSocketConnection" @@ -1164,7 +1170,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.4-dev" + "dev-master": "2.7-dev" } }, "autoload": { @@ -1174,21 +1180,32 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-2.1" + "LGPL-2.1-or-later" ], "authors": [ { - "name": "Alvaro Videla" + "name": "Alvaro Videla", + "role": "Original Maintainer" + }, + { + "name": "John Kelly", + "email": "johnmkelly86@gmail.com", + "role": "Maintainer" + }, + { + "name": "Raúl Araya", + "email": "nubeiro@gmail.com", + "role": "Maintainer" } ], - "description": "This library is a pure PHP implementation of the AMQP protocol. It's been tested against RabbitMQ.", - "homepage": "https://github.com/videlalvaro/php-amqplib/", + "description": "Formerly videlalvaro/php-amqplib. This library is a pure PHP implementation of the AMQP protocol. It's been tested against RabbitMQ.", + "homepage": "https://github.com/php-amqplib/php-amqplib/", "keywords": [ "message", "queue", "rabbitmq" ], - "time": "2015-08-11T12:30:09+00:00" + "time": "2018-02-11T19:28:00+00:00" }, { "name": "phpseclib/mcrypt_compat", From be016300163dfd5016ec3b8bc967b393967d23a3 Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Wed, 21 Mar 2018 05:45:11 -0500 Subject: [PATCH 127/668] magento-engcom/bulk-api#4 Support for Async operations in WebAPI - fixed static tests --- .../Rest/AsynchronousRequestProcessor.php | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php index c16b69a6fe9fe..e5feda6859bb2 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php @@ -16,7 +16,7 @@ class AsynchronousRequestProcessor implements RequestProcessorInterface { - const PROCESSOR_PATH = 'async/V1'; + const PROCESSOR_PATH = "/async/V\\d+/"; /** * @var \Magento\Framework\Webapi\Rest\Response @@ -58,7 +58,8 @@ public function __construct( MassSchedule $asyncBulkPublisher, WebApiAsyncConfig $webapiAsyncConfig, DataObjectProcessor $dataObjectProcessor - ) { + ) + { $this->response = $response; $this->inputParamsResolver = $inputParamsResolver; $this->asyncBulkPublisher = $asyncBulkPublisher; @@ -95,20 +96,12 @@ public function process(\Magento\Framework\Webapi\Rest\Request $request) ); $this->response->setStatusCode(RestResponse::STATUS_CODE_202) - ->prepareResponse($responseData); + ->prepareResponse($responseData); } catch (\Exception $e) { $this->response->setException($e); } } - /** - * {@inheritdoc} - */ - public function getProcessorPath() - { - return self::PROCESSOR_PATH; - } - /** * @param \Magento\Framework\Webapi\Rest\Request $request * @return string @@ -126,8 +119,9 @@ private function getTopicName($request) /** * {@inheritdoc} */ - public function canProcess(\Magento\Framework\Webapi\Rest\Request $request) { - if (strpos(ltrim($request->getPathInfo(), '/'), $this->getProcessorPath()) === 0) { + public function canProcess(\Magento\Framework\Webapi\Rest\Request $request) + { + if (preg_match(self::PROCESSOR_PATH, ltrim($request->getPathInfo(), '/')) === 0) { return true; } return false; From 512ea2144b3f08e76f6a0c3bfc2f87154cdd84ef Mon Sep 17 00:00:00 2001 From: Illia Grybkov <igrybkov@magento.com> Date: Wed, 21 Mar 2018 15:04:18 +0200 Subject: [PATCH 128/668] MAGETWO-89395: Encryption support - Remove tests variation related to unused cryptographic algorithms --- .../Unit/Crypt/_files/_crypt_fixtures.php | 200 +----------------- .../Encryption/Test/Unit/CryptTest.php | 24 +-- 2 files changed, 15 insertions(+), 209 deletions(-) diff --git a/lib/internal/Magento/Framework/Encryption/Test/Unit/Crypt/_files/_crypt_fixtures.php b/lib/internal/Magento/Framework/Encryption/Test/Unit/Crypt/_files/_crypt_fixtures.php index 1b96b756f5ff0..c187d8d61bea6 100644 --- a/lib/internal/Magento/Framework/Encryption/Test/Unit/Crypt/_files/_crypt_fixtures.php +++ b/lib/internal/Magento/Framework/Encryption/Test/Unit/Crypt/_files/_crypt_fixtures.php @@ -14,38 +14,6 @@ 5 => '', ], 1 => [ - 0 => 'cc188f97f1bbd2f7a265e57c0dbb004ac29c1a88dc846ea6aed1c80c', - 1 => 'blowfish', - 2 => 'cbc', - 3 => '48da27c4', - 4 => '', - 5 => '', - ], - 2 => [ - 0 => '8bf1685366faa72ce1e4fbe1f89656e1de1fd186331c8fa255dde0eb', - 1 => 'blowfish', - 2 => 'cfb', - 3 => '70c1592a', - 4 => '', - 5 => '', - ], - 3 => [ - 0 => '5d304b80fbe2f6d6eaa51103d7558368e15f843b005fbd6353b7d0dd', - 1 => 'blowfish', - 2 => 'ofb', - 3 => 'a8e85663', - 4 => '', - 5 => '', - ], - 4 => [ - 0 => 'f33d7a68248758b77863569a9caa08271fcda17eb3903e8c8f01ea48', - 1 => 'blowfish', - 2 => 'nofb', - 3 => '5919959b', - 4 => '', - 5 => '', - ], - 5 => [ 0 => '7e34794ae07b3540a683cfd47b24a039', 1 => 'rijndael-128', 2 => 'ecb', @@ -53,47 +21,7 @@ 4 => '', 5 => '', ], - 6 => [ - 0 => 'eed11fb167c5ba7c6666b0379d3f0efd', - 1 => 'rijndael-128', - 2 => 'cbc', - 3 => 'f87fb9492e358ff7', - 4 => '', - 5 => '', - ], - 7 => [ - 0 => 'b0baa1454a71e4902d2f21cca5822a43', - 1 => 'rijndael-128', - 2 => 'cfb', - 3 => 'ca5f40f310fbf41c', - 4 => '', - 5 => '', - ], - 8 => [ - 0 => '097577dd9bd37a37670d4ffac6db71ca', - 1 => 'rijndael-128', - 2 => 'ofb', - 3 => '9662705b5c8a92e2', - 4 => '', - 5 => '', - ], - 9 => [ - 0 => '26283c5ee61006051e109fb13cbeadd4', - 1 => 'rijndael-128', - 2 => 'nofb', - 3 => 'fbae555d61cb4ab3', - 4 => '', - 5 => '', - ], - 10 => [ - 0 => '912940718c6991dcc9927fe1357a59eb', - 1 => 'rijndael-256', - 2 => 'ecb', - 3 => '6041192a9ed0647219bfba45306be4bc', - 4 => '', - 5 => '', - ], - 11 => [ + 2 => [ 0 => '22eaec79b2ae279beac05375f1dd301f', 1 => 'rijndael-256', 2 => 'cbc', @@ -101,31 +29,7 @@ 4 => '', 5 => '', ], - 12 => [ - 0 => '331ff7ee00849ef02acfcc4a4c44b002', - 1 => 'rijndael-256', - 2 => 'cfb', - 3 => 'e7da553b177006fb878f2189815b146c', - 4 => '', - 5 => '', - ], - 13 => [ - 0 => '52b9991fb182434f8ef64db604c1946a', - 1 => 'rijndael-256', - 2 => 'ofb', - 3 => '95118150491d3acb936fed8f8aad942a', - 4 => '', - 5 => '', - ], - 14 => [ - 0 => '42cba7ea2c940077df289a594170c846', - 1 => 'rijndael-256', - 2 => 'nofb', - 3 => '11211b3d82f6a7d8cc864f3ffee958c1', - 4 => '', - 5 => '', - ], - 15 => [ + 3 => [ 0 => '72f761d4c435986911087485b8664d40b28d12f818eca42edf84fecd', 1 => 'blowfish', 2 => 'ecb', @@ -133,39 +37,7 @@ 4 => 'Hello world!!!', 5 => 'UObRTUnq3jCNZjJOxwNubA==', ], - 16 => [ - 0 => '63341175e4edd8ef27ea0d754f985b6bbfddd29b381ea8473a450b8c', - 1 => 'blowfish', - 2 => 'cbc', - 3 => '8cc63606', - 4 => 'Hello world!!!', - 5 => '18QUXHt++6HiTQynQ4nUkg==', - ], - 17 => [ - 0 => '5c4beba2e7571460dd0c2a6971dec5d707b6d8681a69e927ba8fac9f', - 1 => 'blowfish', - 2 => 'cfb', - 3 => 'e93e050d', - 4 => 'Hello world!!!', - 5 => '11ubM60SiGkecJRFZMQ=', - ], - 18 => [ - 0 => '073f901024e51b0ab85cf5944a90aea92bf353083ff642024f61a62d', - 1 => 'blowfish', - 2 => 'ofb', - 3 => 'a9b4f0ca', - 4 => 'Hello world!!!', - 5 => 'SqliQR1lHxY4r/HCgoI=', - ], - 19 => [ - 0 => '56df989b718351624480eb7776f827da7caf7996a6aa38dfa3e7328a', - 1 => 'blowfish', - 2 => 'nofb', - 3 => '4178906f', - 4 => 'Hello world!!!', - 5 => 'vkPrtkjZ9TPapsG1sEY=', - ], - 20 => [ + 4 => [ 0 => '6f326ec41c0e1d17fc030018043c0862', 1 => 'rijndael-128', 2 => 'ecb', @@ -173,47 +45,7 @@ 4 => 'Hello world!!!', 5 => 'dYsG1NhOM0lvXj32RqXJuw==', ], - 21 => [ - 0 => '7891bd79c8bae053e795733dd6b99d4e', - 1 => 'rijndael-128', - 2 => 'cbc', - 3 => '11e5244c25e3cdc2', - 4 => 'Hello world!!!', - 5 => '5rMjKp16UzjD1rxcTFqNfg==', - ], - 22 => [ - 0 => '247ec5c7e7fa07628090ed1e07bc601f', - 1 => 'rijndael-128', - 2 => 'cfb', - 3 => '7afdde5cb2adca91', - 4 => 'Hello world!!!', - 5 => 'OOhZb1g3owMU05jD2qk=', - ], - 23 => [ - 0 => '0cedc5085da7c010a4136f7cc4c8f073', - 1 => 'rijndael-128', - 2 => 'ofb', - 3 => 'f7cf137c927714de', - 4 => 'Hello world!!!', - 5 => 'iq9Kx0artzuKew+HWpU=', - ], - 24 => [ - 0 => 'a0374d4b62c0394e01407f4133bc61c1', - 1 => 'rijndael-128', - 2 => 'nofb', - 3 => '282ff6bb6270b4e5', - 4 => 'Hello world!!!', - 5 => 'gO5d+xbHk8E+8EH308E=', - ], - 25 => [ - 0 => 'afa6f9c61c9199e2e4b6a1426dead6d4', - 1 => 'rijndael-256', - 2 => 'ecb', - 3 => '1ae41175585077595667ef251d8f74e4', - 4 => 'Hello world!!!', - 5 => 'qTO/oVNzMhFZCnjCY90IuMuJcb7UVa7SXygKHWExX70=', - ], - 26 => [ + 5 => [ 0 => '774bb6dac74b24796469d1865df679be', 1 => 'rijndael-256', 2 => 'cbc', @@ -221,28 +53,4 @@ 4 => 'Hello world!!!', 5 => '4APJzBRpwuZSqbIfr/GPS+Zb8wV/uo9qNSOvk68cGRM=', ], - 27 => [ - 0 => '0a319daff472006ec9d10a70920dd592', - 1 => 'rijndael-256', - 2 => 'cfb', - 3 => '99fa50190792623b19a62a2d59b40105', - 4 => 'Hello world!!!', - 5 => 'GbcnmzgYRB+4ETtw5zQ=', - ], - 28 => [ - 0 => '4fbd81fce821dd6042b46051eddcc300', - 1 => 'rijndael-256', - 2 => 'ofb', - 3 => 'b78b752f32a9788347f6f70e7a5fe1f0', - 4 => 'Hello world!!!', - 5 => 'PvbnFhmV0tej2c6zVIc=', - ], - 29 => [ - 0 => 'c183b2078424e7c9c129ba425421c0eb', - 1 => 'rijndael-256', - 2 => 'nofb', - 3 => '97b3940cce9106b7c5a7f266f0a334bd', - 4 => 'Hello world!!!', - 5 => '2HhsW5Wlw9glUVy9mGo=', - ], ]; diff --git a/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php b/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php index 55a078aaade7d..2aacd2f2c07d0 100644 --- a/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php +++ b/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php @@ -15,14 +15,10 @@ class CryptTest extends \PHPUnit\Framework\TestCase private static $_cipherInfo; - protected $_supportedCiphers = [MCRYPT_BLOWFISH, MCRYPT_RIJNDAEL_128, MCRYPT_RIJNDAEL_256]; - - protected $_supportedModes = [ - MCRYPT_MODE_ECB, - MCRYPT_MODE_CBC, - MCRYPT_MODE_CFB, - MCRYPT_MODE_OFB, - MCRYPT_MODE_NOFB, + private const SUPPORTED_CIPHER_MODE_COMBINATIONS = [ + MCRYPT_BLOWFISH => [MCRYPT_MODE_ECB], + MCRYPT_RIJNDAEL_128 => [MCRYPT_MODE_ECB], + MCRYPT_RIJNDAEL_256 => [MCRYPT_MODE_CBC], ]; protected function setUp() @@ -76,11 +72,12 @@ protected function _getInitVectorSize($cipherName, $modeName) return self::$_cipherInfo[$cipherName][$modeName]['iv_size']; } - public function getCipherModeCombinations() + public function getCipherModeCombinations(): array { $result = []; - foreach ($this->_supportedCiphers as $cipher) { - foreach ($this->_supportedModes as $mode) { + foreach (self::SUPPORTED_CIPHER_MODE_COMBINATIONS as $cipher => $modes) { + /** @var array $modes */ + foreach ($modes as $mode) { $result[$cipher . '-' . $mode] = [$cipher, $mode]; } } @@ -105,8 +102,9 @@ public function testConstructor($cipher, $mode) public function getConstructorExceptionData() { $result = []; - foreach ($this->_supportedCiphers as $cipher) { - foreach ($this->_supportedModes as $mode) { + foreach (self::SUPPORTED_CIPHER_MODE_COMBINATIONS as $cipher => $modes) { + /** @var array $modes */ + foreach ($modes as $mode) { $tooLongKey = str_repeat('-', $this->_getKeySize($cipher, $mode) + 1); $tooShortInitVector = str_repeat('-', $this->_getInitVectorSize($cipher, $mode) - 1); $tooLongInitVector = str_repeat('-', $this->_getInitVectorSize($cipher, $mode) + 1); From f333d65a5d34c056829b8f8790c6425d6add4f12 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 21 Mar 2018 10:30:27 -0500 Subject: [PATCH 129/668] MAGETWO-89292: Implement SDL from prototype - supporting multiple docs --- .../Magento/CatalogGraphQl/etc/schema.graphql | 31 +++++++++++------ app/code/Magento/GraphQl/etc/schema.graphql | 15 ++++---- .../GraphQl/Config/Data/DataFactory.php | 12 ++++--- .../GraphQl/Config/Data/Enum/Value.php | 19 ++++++++++- .../GraphQl/Config/Data/Mapper/EnumMapper.php | 9 +++-- .../GraphQl/Config/GraphQlReader.php | 10 +++--- .../MetaReader/FieldMetaReader.php | 4 +++ .../MetaReader/TypeMetaReader.php | 32 +++++++++++++++-- .../Config/GraphQlReader/Reader/EnumType.php | 34 ++++++++++++++++++- .../GraphQlReader/Reader/InputObjectType.php | 27 +++++++++++++++ .../GraphQlReader/Reader/InterfaceType.php | 27 +++++++++++++++ .../Framework/GraphQl/Type/Enum/Enum.php | 4 ++- 12 files changed, 190 insertions(+), 34 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphql b/app/code/Magento/CatalogGraphQl/etc/schema.graphql index c35997669727a..8676dc37a397d 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphql +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphql @@ -1,5 +1,13 @@ type Query { - products(search: String, filter: ProductFilterInput, pageSize: Int, currentPage: Int, sort: ProductSortInput): Products @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") + products( + search: String @doc(description: "comment for search."), + filter: ProductFilterInput, + pageSize: Int, + currentPage: Int, + sort: ProductSortInput + ): Products + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") + @doc(description: "comment for products.") } enum CurrencyEnum { @@ -242,8 +250,11 @@ type ProductTierPrices { website_id: Float } -interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") { - id: Int +interface ProductInterface +@typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") +@doc(description: "comment for ProductInterface.") +{ + id: Int @doc(description: "comment for [ProductInterface].") name: String sku: String description: String @@ -439,7 +450,8 @@ type VirtualProduct implements ProductInterface, CustomizableProductInterface { manufacturer: Int } -type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface { +type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface +@doc(description: "comment for items[ProductInterface].") { id: Int name: String sku: String @@ -485,13 +497,12 @@ type SimpleProduct implements ProductInterface, PhysicalProductInterface, Custom manufacturer: Int } -type Products { - items: [ProductInterface] +type Products @doc(description:"Comment for Products") { + items: [ProductInterface] @doc(description: "comment for items[ProductInterface].") page_info: SearchResultPageInfo @doc(description: "comment for page_info.") total_count: Int } - input ProductFilterInput { name: FilterTypeInput sku: FilterTypeInput @@ -547,8 +558,8 @@ type ProductMediaGalleryEntriesVideoContent { video_metadata: String } -input ProductSortInput { - name: SortEnum +input ProductSortInput @doc(description:"Input ProductSortInput") { + name: SortEnum @doc(description:"Name") sku: SortEnum description: SortEnum short_description: SortEnum @@ -589,7 +600,7 @@ input ProductSortInput { type MediaGalleryEntry @doc(description: "comment for MediaGalleryEntry") { - id: Int + id: Int @doc(description: "id for MediaGalleryEntry") media_type: String label: String position: Int diff --git a/app/code/Magento/GraphQl/etc/schema.graphql b/app/code/Magento/GraphQl/etc/schema.graphql index 50d20f1ff769e..d0fd735a81ccc 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphql +++ b/app/code/Magento/GraphQl/etc/schema.graphql @@ -1,9 +1,9 @@ type Query { - placeholder: String + placeholder: String @doc(description: "comment for placeholder.") } -input FilterTypeInput { - eq: String +input FilterTypeInput @doc(description:"Comment for FilterTypeInput") { + eq: String @doc(description:"Equal") finset: [String] from: String gt: String @@ -23,11 +23,12 @@ input FilterTypeInput { type SearchResultPageInfo @doc(description:"Comment for SearchResultPageInfo") { - page_size: Int - current_page: Int + page_size: Int @doc(description:"Comment for page_size") + current_page: Int @doc(description:"Comment for current_page") } -enum SortEnum { - ASC +enum SortEnum @doc(description: "comment for SortEnum.") +{ + ASC @doc(description:"Ascending") DESC } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php index 45e722f66c8dc..bb95b2f5223d8 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php @@ -142,15 +142,17 @@ public function createInterface( * * @param string $name * @param string $value + * @param string $description * @return Value */ - public function createValue(string $name, string $value): Value + public function createValue(string $name, string $value, string $description = ''): Value { return $this->objectManager->create( Value::class, [ 'name' => $name, - 'value' => $value + 'value' => $value, + 'description' => $description ] ); } @@ -162,15 +164,17 @@ public function createValue(string $name, string $value): Value * * @param string $name * @param array $values + * @param string $description * @return Enum */ - public function createEnum(string $name, array $values): Enum + public function createEnum(string $name, array $values, string $description = ''): Enum { return $this->objectManager->create( Enum::class, [ 'name' => $name, - 'values' => $values + 'values' => $values, + 'description' => $description ] ); } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Enum/Value.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Enum/Value.php index 0f6908ace1430..5b940d2d7dce4 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Enum/Value.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Enum/Value.php @@ -22,14 +22,21 @@ class Value */ private $value; + /** + * @var string + */ + private $description; + /** * @param string $name * @param string $value + * @param string $description */ - public function __construct(string $name, string $value) + public function __construct(string $name, string $value, string $description = '') { $this->name = $name; $this->value = $value; + $this->description = $description; } /** @@ -51,4 +58,14 @@ public function getValue() : string { return $this->value; } + + /** + * Get the enum value's description. + * + * @return string + */ + public function getDescription() : string + { + return $this->description; + } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/EnumMapper.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/EnumMapper.php index 551e592d10710..5e2b4c1142fb5 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/EnumMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Mapper/EnumMapper.php @@ -40,11 +40,16 @@ public function map(array $data): StructureInterface { $values = []; foreach ($data['items'] as $item) { - $values[$item['_value']] = $this->dataFactory->createValue($item['name'], $item['_value']); + $values[$item['_value']] = $this->dataFactory->createValue( + $item['name'], + $item['_value'], + isset($item['description']) ? $item['description'] : '' + ); } return $this->dataFactory->createEnum( $data['name'], - $values + $values, + isset($data['description']) ? $data['description'] : '' ); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php index 80bbff36c1672..ea7a98e849e74 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php @@ -102,14 +102,12 @@ public function read($scope = null) : array private function parseTypes($graphQlSchemaContent) : array { $typeKindsPattern = '(type|interface|union|enum|input)'; - $typeNamePattern = '[_A-Za-z][_0-9A-Za-z]*'; - $typeDefinitionPattern = '.*\{[^\}]*\}'; - $spacePattern = '[\s\t\n\r]*'; - $annotationsPattern = '(@.*[\s\t\n\r]*){0,}'; + $typeNamePattern = '[_A-Za-z][_0-9A-Za-z]+'; + $typeDefinitionPattern = '[^\{]*(\{[^\}]*\})'; + $spacePattern = '[\s\t\n\r]+'; preg_match_all( - "/{$typeKindsPattern}{$spacePattern}({$typeNamePattern})" - . "{$spacePattern}{$annotationsPattern}{$typeDefinitionPattern}/i", + "/{$typeKindsPattern}{$spacePattern}({$typeNamePattern}){$spacePattern}{$typeDefinitionPattern}/i", $graphQlSchemaContent, $matches ); diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php index 19bf9468d5b93..e859301b99f00 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php @@ -60,6 +60,10 @@ public function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMet $result['arguments'][$argumentName], $this->typeMetaReader->readTypeMeta($typeMeta, 'Argument') ); + + if (!empty($argumentMeta->astNode->directives) && !($argumentMeta instanceof \GraphQL\Type\Definition\ScalarType)) { + $result['arguments'][$argumentName]['description'] = $this->readTypeDescription($argumentMeta); + } } return $result; } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php index 891ebb81db722..af37995d4d889 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php @@ -19,6 +19,11 @@ class TypeMetaReader public function readTypeMeta($meta, $parameterType = 'Argument') : array { $result = []; + + if (!empty($meta->astNode->directives) && !($meta instanceof \GraphQL\Type\Definition\ScalarType)) { + $result['description'] = $this->readTypeDescription($meta); + } + if ($meta instanceof \GraphQL\Type\Definition\NonNull) { $result['required'] = true; $meta = $meta->getWrappedType(); @@ -33,7 +38,7 @@ public function readTypeMeta($meta, $parameterType = 'Argument') : array } else { $result['itemsRequired'] = false; } - $result['description'] = $itemTypeMeta->description; + //$result['description'] = $itemTypeMeta->description; $itemTypeName = $itemTypeMeta->name; $result['itemType'] = $itemTypeName; if ($this->isScalarType((string)$itemTypeMeta)) { @@ -42,9 +47,10 @@ public function readTypeMeta($meta, $parameterType = 'Argument') : array $result['type'] = 'ObjectArray' . $parameterType; } } else { - $result['description'] = $meta->description; + //$result['description'] = $meta->description; $result['type'] = $meta->name; } + return $result; } @@ -58,4 +64,26 @@ private function isScalarType(string $type) : bool { return in_array($type, ['String', 'Int', 'Float', 'Boolean', 'ID']); } + + /** + * Read documentation annotation for a specific type + * + * @param $meta + * @return string + */ + private function readTypeDescription($meta) : string + { + /** @var \GraphQL\Language\AST\NodeList $directives */ + $directives = $meta->astNode->directives; + foreach ($directives as $directive) { + if ($directive->name->value == 'doc') { + foreach ($directive->arguments as $directiveArgument) { + if ($directiveArgument->name->value == 'description') { + return $directiveArgument->value->value; + } + } + } + } + return ''; + } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php index 1e90939df5cf8..a4053cba5fb3b 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php @@ -23,16 +23,48 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array 'items' => [] // Populated later ]; foreach ($typeMeta->getValues() as $value) { + $description = ''; + if (!empty($value->astNode->directives)) { + $description = $this->readTypeDescription($value); + } + // TODO: Simplify structure, currently name is lost during conversion to GraphQL schema $result['items'][$value->value] = [ 'name' => strtolower($value->name), - '_value' => $value->value + '_value' => $value->value, + 'description' => $description ]; } + if (!empty($typeMeta->astNode->directives) && !($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { + $result['description'] = $this->readTypeDescription($typeMeta); + } + return $result; } else { return null; } } + + /** + * Read documentation annotation for a specific type + * + * @param $meta + * @return string + */ + private function readTypeDescription($meta) : string + { + /** @var \GraphQL\Language\AST\NodeList $directives */ + $directives = $meta->astNode->directives; + foreach ($directives as $directive) { + if ($directive->name->value == 'doc') { + foreach ($directive->arguments as $directiveArgument) { + if ($directiveArgument->name->value == 'description') { + return $directiveArgument->value->value; + } + } + } + } + return ''; + } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php index 45669d6f37314..b815f1a7cf9a9 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php @@ -63,6 +63,33 @@ private function readInputObjectFieldMeta(\GraphQL\Type\Definition\InputObjectFi ]; $result = array_merge($result, $this->typeMetaReader->readTypeMeta($typeMeta, 'InputField')); + + if (!empty($fieldMeta->astNode->directives) && !($fieldMeta instanceof \GraphQL\Type\Definition\ScalarType)) { + $result['description'] = $this->readTypeDescription($fieldMeta); + } + return $result; } + + /** + * Read documentation annotation for a specific type + * + * @param $meta + * @return string + */ + private function readTypeDescription($meta) : string + { + /** @var \GraphQL\Language\AST\NodeList $directives */ + $directives = $meta->astNode->directives; + foreach ($directives as $directive) { + if ($directive->name->value == 'doc') { + foreach ($directive->arguments as $directiveArgument) { + if ($directiveArgument->name->value == 'description') { + return $directiveArgument->value->value; + } + } + } + } + return ''; + } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php index 39c696c857f2f..db3ee795a6c98 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php @@ -48,6 +48,11 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array foreach ($fields as $fieldName => $fieldMeta) { $result['fields'][$fieldName] = $this->fieldMetaReader->readFieldMeta($fieldMeta); } + + if (!empty($typeMeta->astNode->directives) && !($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { + $result['description'] = $this->readTypeDescription($typeMeta); + } + return $result; } else { return null; @@ -75,4 +80,26 @@ private function getInterfaceTypeResolver(\GraphQL\Type\Definition\InterfaceType } return null; } + + /** + * Read documentation annotation for a specific type + * + * @param $meta + * @return string + */ + private function readTypeDescription($meta) : string + { + /** @var \GraphQL\Language\AST\NodeList $directives */ + $directives = $meta->astNode->directives; + foreach ($directives as $directive) { + if ($directive->name->value == 'doc') { + foreach ($directive->arguments as $directiveArgument) { + if ($directiveArgument->name->value == 'description') { + return $directiveArgument->value->value; + } + } + } + } + return ''; + } } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php b/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php index 1d6a85d185d74..bfa5e28b3b5b8 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Enum/Enum.php @@ -22,10 +22,12 @@ public function __construct(EnumStructure $structure) { $config = [ 'name' => $structure->getName(), + 'description' => $structure->getDescription(), ]; foreach ($structure->getValues() as $value) { $config['values'][$value->getValue()] = [ - 'value' => $value->getValue() + 'value' => $value->getValue(), + 'description' => $value->getDescription() ]; } parent::__construct($config); From b9b76bfa427b8d247541096101f877d420bcab93 Mon Sep 17 00:00:00 2001 From: Jacob Brown <jacob@gnu.org> Date: Wed, 21 Mar 2018 11:05:07 -0500 Subject: [PATCH 130/668] MAGETWO-89389: Update 3rd-party libraries to correspond versions used in Magento 2.2 --- composer.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 754be9fffec9a..b566641b2ce68 100644 --- a/composer.json +++ b/composer.json @@ -30,9 +30,9 @@ "ext-xsl": "*", "ext-zip": "*", "lib-libxml": "*", - "braintree/braintree_php": "3.22.0", + "braintree/braintree_php": "3.28.0", "colinmollenhour/cache-backend-file": "1.4", - "colinmollenhour/cache-backend-redis": "1.10.2", + "colinmollenhour/cache-backend-redis": "1.10.4", "colinmollenhour/credis": "1.8.2", "colinmollenhour/php-redis-session-abstract": "~1.3.8", "composer/composer": "1.4.1", @@ -45,12 +45,12 @@ "pelago/emogrifier": "^2.0.0", "php-amqplib/php-amqplib": "2.5.*", "phpseclib/phpseclib": "2.0.*", - "ramsey/uuid": "3.6.1", + "ramsey/uuid": "~3.7.3", "symfony/console": "~2.3, !=2.7.0", "symfony/event-dispatcher": "~2.1", "symfony/process": "~2.1", - "tedivm/jshrink": "~1.1.0", - "tubalmartin/cssmin": "4.1.0", + "tedivm/jshrink": "~1.3.0", + "tubalmartin/cssmin": "4.1.1", "webonyx/graphql-php": "^0.11.1", "zendframework/zend-captcha": "^2.7.1", "zendframework/zend-code": "^3.1.0", @@ -83,11 +83,11 @@ "require-dev": { "friendsofphp/php-cs-fixer": "~2.1.1", "lusitanian/oauth": "~0.8.10", - "pdepend/pdepend": "2.5.0", + "pdepend/pdepend": "2.5.2", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.2.0", "sebastian/phpcpd": "2.0.4", - "squizlabs/php_codesniffer": "3.0.1" + "squizlabs/php_codesniffer": "3.2.2" }, "replace": { "magento/module-marketplace": "100.3.0-dev", From e86f9c7d568fd1233a97080a9d6181cdcead04fa Mon Sep 17 00:00:00 2001 From: Jacob Brown <jacob@gnu.org> Date: Wed, 21 Mar 2018 11:13:19 -0500 Subject: [PATCH 131/668] MAGETWO-89389: Update 3rd-party libraries to correspond versions used in Magento 2.2 --- composer.lock | 325 +++++++++++++++++++++++++------------------------- 1 file changed, 162 insertions(+), 163 deletions(-) diff --git a/composer.lock b/composer.lock index 7dc6b64f20be1..b3295d0195ce9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,21 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "1052c147f8bf4c3a3c27b032aec1b9a5", + "hash": "d9c7eabad392876d65ff2c473a8b2853", + "content-hash": "6b8db52d9aae8078eded76556d6ac879", "packages": [ { "name": "braintree/braintree_php", - "version": "3.22.0", + "version": "3.28.0", "source": { "type": "git", "url": "https://github.com/braintree/braintree_php.git", - "reference": "402617b803779bed5ae899209afa75ef9950becc" + "reference": "f8ab5ca7b3397536de622fc9640e5b257fc33e71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/braintree/braintree_php/zipball/402617b803779bed5ae899209afa75ef9950becc", - "reference": "402617b803779bed5ae899209afa75ef9950becc", + "url": "https://api.github.com/repos/braintree/braintree_php/zipball/f8ab5ca7b3397536de622fc9640e5b257fc33e71", + "reference": "f8ab5ca7b3397536de622fc9640e5b257fc33e71", "shasum": "" }, "require": { @@ -47,11 +48,11 @@ "authors": [ { "name": "Braintree", - "homepage": "http://www.braintreepayments.com" + "homepage": "https://www.braintreepayments.com" } ], "description": "Braintree PHP Client Library", - "time": "2017-02-16T19:59:04+00:00" + "time": "2018-02-08 23:03:34" }, { "name": "colinmollenhour/cache-backend-file", @@ -87,20 +88,20 @@ ], "description": "The stock Zend_Cache_Backend_File backend has extremely poor performance for cleaning by tags making it become unusable as the number of cached items increases. This backend makes many changes resulting in a huge performance boost, especially for tag cleaning.", "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_File", - "time": "2016-05-02T16:24:47+00:00" + "time": "2016-05-02 16:24:47" }, { "name": "colinmollenhour/cache-backend-redis", - "version": "1.10.2", + "version": "1.10.4", "source": { "type": "git", "url": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis.git", - "reference": "18b33e4b69cf15747ab98b4f2c98ab445da05abd" + "reference": "6bf0a4b7a3f8dc4a6255fad5b6e42213253d9972" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_Redis/zipball/18b33e4b69cf15747ab98b4f2c98ab445da05abd", - "reference": "18b33e4b69cf15747ab98b4f2c98ab445da05abd", + "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_Redis/zipball/6bf0a4b7a3f8dc4a6255fad5b6e42213253d9972", + "reference": "6bf0a4b7a3f8dc4a6255fad5b6e42213253d9972", "shasum": "" }, "require": { @@ -123,7 +124,7 @@ ], "description": "Zend_Cache backend using Redis with full support for tags.", "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis", - "time": "2017-03-25T04:54:24+00:00" + "time": "2017-10-05 20:50:44" }, { "name": "colinmollenhour/credis", @@ -163,7 +164,7 @@ ], "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", "homepage": "https://github.com/colinmollenhour/credis", - "time": "2017-07-05T15:32:38+00:00" + "time": "2017-07-05 15:32:38" }, { "name": "colinmollenhour/php-redis-session-abstract", @@ -200,7 +201,7 @@ ], "description": "A Redis-based session handler with optimistic locking", "homepage": "https://github.com/colinmollenhour/php-redis-session-abstract", - "time": "2018-01-08T14:53:13+00:00" + "time": "2018-01-08 14:53:13" }, { "name": "composer/ca-bundle", @@ -256,7 +257,7 @@ "ssl", "tls" ], - "time": "2017-11-29T09:37:33+00:00" + "time": "2017-11-29 09:37:33" }, { "name": "composer/composer", @@ -333,7 +334,7 @@ "dependency", "package" ], - "time": "2017-03-10T08:29:45+00:00" + "time": "2017-03-10 08:29:45" }, { "name": "composer/semver", @@ -395,7 +396,7 @@ "validation", "versioning" ], - "time": "2016-08-30T16:08:34+00:00" + "time": "2016-08-30 16:08:34" }, { "name": "composer/spdx-licenses", @@ -456,7 +457,7 @@ "spdx", "validator" ], - "time": "2018-01-31T13:17:27+00:00" + "time": "2018-01-31 13:17:27" }, { "name": "container-interop/container-interop", @@ -487,7 +488,7 @@ ], "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", "homepage": "https://github.com/container-interop/container-interop", - "time": "2017-02-14T19:40:03+00:00" + "time": "2017-02-14 19:40:03" }, { "name": "elasticsearch/elasticsearch", @@ -542,7 +543,7 @@ "elasticsearch", "search" ], - "time": "2017-11-08T17:04:47+00:00" + "time": "2017-11-08 17:04:47" }, { "name": "guzzlehttp/ringphp", @@ -593,7 +594,7 @@ } ], "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.", - "time": "2015-05-20T03:37:09+00:00" + "time": "2015-05-20 03:37:09" }, { "name": "guzzlehttp/streams", @@ -643,7 +644,7 @@ "Guzzle", "stream" ], - "time": "2014-10-12T19:18:40+00:00" + "time": "2014-10-12 19:18:40" }, { "name": "justinrainbow/json-schema", @@ -709,7 +710,7 @@ "json", "schema" ], - "time": "2017-10-21T13:15:38+00:00" + "time": "2017-10-21 13:15:38" }, { "name": "magento/composer", @@ -745,7 +746,7 @@ "AFL-3.0" ], "description": "Magento composer library helps to instantiate Composer application and run composer commands.", - "time": "2017-04-24T09:57:02+00:00" + "time": "2017-04-24 09:57:02" }, { "name": "magento/magento-composer-installer", @@ -824,7 +825,7 @@ "composer-installer", "magento" ], - "time": "2017-12-29T16:45:24+00:00" + "time": "2017-12-29 16:45:24" }, { "name": "magento/zendframework1", @@ -871,7 +872,7 @@ "ZF1", "framework" ], - "time": "2017-06-21T14:56:23+00:00" + "time": "2017-06-21 14:56:23" }, { "name": "monolog/monolog", @@ -949,7 +950,7 @@ "logging", "psr-3" ], - "time": "2017-06-19T01:22:40+00:00" + "time": "2017-06-19 01:22:40" }, { "name": "oyejorge/less.php", @@ -1011,7 +1012,7 @@ "php", "stylesheet" ], - "time": "2017-03-28T22:19:25+00:00" + "time": "2017-03-28 22:19:25" }, { "name": "paragonie/random_compat", @@ -1059,7 +1060,7 @@ "pseudorandom", "random" ], - "time": "2017-09-27T21:40:39+00:00" + "time": "2017-09-27 21:40:39" }, { "name": "pelago/emogrifier", @@ -1128,7 +1129,7 @@ "email", "pre-processing" ], - "time": "2018-01-05T23:30:21+00:00" + "time": "2018-01-05 23:30:21" }, { "name": "php-amqplib/php-amqplib", @@ -1182,7 +1183,7 @@ "queue", "rabbitmq" ], - "time": "2015-08-11T12:30:09+00:00" + "time": "2015-08-11 12:30:09" }, { "name": "phpseclib/phpseclib", @@ -1274,7 +1275,7 @@ "x.509", "x509" ], - "time": "2017-11-29T06:38:08+00:00" + "time": "2017-11-29 06:38:08" }, { "name": "psr/container", @@ -1323,7 +1324,7 @@ "container-interop", "psr" ], - "time": "2017-02-14T16:28:37+00:00" + "time": "2017-02-14 16:28:37" }, { "name": "psr/log", @@ -1370,20 +1371,20 @@ "psr", "psr-3" ], - "time": "2016-10-10T12:19:37+00:00" + "time": "2016-10-10 12:19:37" }, { "name": "ramsey/uuid", - "version": "3.6.1", + "version": "3.7.3", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "4ae32dd9ab8860a4bbd750ad269cba7f06f7934e" + "reference": "44abcdad877d9a46685a3a4d221e3b2c4b87cb76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/4ae32dd9ab8860a4bbd750ad269cba7f06f7934e", - "reference": "4ae32dd9ab8860a4bbd750ad269cba7f06f7934e", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/44abcdad877d9a46685a3a4d221e3b2c4b87cb76", + "reference": "44abcdad877d9a46685a3a4d221e3b2c4b87cb76", "shasum": "" }, "require": { @@ -1394,17 +1395,15 @@ "rhumsaa/uuid": "self.version" }, "require-dev": { - "apigen/apigen": "^4.1", - "codeception/aspect-mock": "^1.0 | ^2.0", + "codeception/aspect-mock": "^1.0 | ~2.0.0", "doctrine/annotations": "~1.2.0", "goaop/framework": "1.0.0-alpha.2 | ^1.0 | ^2.1", "ircmaxell/random-lib": "^1.1", "jakub-onderka/php-parallel-lint": "^0.9.0", - "mockery/mockery": "^0.9.4", + "mockery/mockery": "^0.9.9", "moontoast/math": "^1.1", "php-mock/php-mock-phpunit": "^0.3|^1.1", - "phpunit/phpunit": "^4.7|>=5.0 <5.4", - "satooshi/php-coveralls": "^0.6.1", + "phpunit/phpunit": "^4.7|^5.0", "squizlabs/php_codesniffer": "^2.3" }, "suggest": { @@ -1452,7 +1451,7 @@ "identifier", "uuid" ], - "time": "2017-03-26T20:37:53+00:00" + "time": "2018-01-20 00:28:24" }, { "name": "react/promise", @@ -1498,7 +1497,7 @@ "promise", "promises" ], - "time": "2017-03-25T12:08:31+00:00" + "time": "2017-03-25 12:08:31" }, { "name": "seld/cli-prompt", @@ -1546,7 +1545,7 @@ "input", "prompt" ], - "time": "2017-03-18T11:32:45+00:00" + "time": "2017-03-18 11:32:45" }, { "name": "seld/jsonlint", @@ -1595,7 +1594,7 @@ "parser", "validator" ], - "time": "2018-01-24T12:46:19+00:00" + "time": "2018-01-24 12:46:19" }, { "name": "seld/phar-utils", @@ -1639,7 +1638,7 @@ "keywords": [ "phra" ], - "time": "2015-10-13T18:44:15+00:00" + "time": "2015-10-13 18:44:15" }, { "name": "symfony/console", @@ -1700,7 +1699,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-01-29T08:54:45+00:00" + "time": "2018-01-29 08:54:45" }, { "name": "symfony/debug", @@ -1757,7 +1756,7 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2016-07-30T07:22:48+00:00" + "time": "2016-07-30 07:22:48" }, { "name": "symfony/event-dispatcher", @@ -1817,7 +1816,7 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:36:31+00:00" + "time": "2018-01-03 07:36:31" }, { "name": "symfony/filesystem", @@ -1866,7 +1865,7 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" + "time": "2018-01-03 07:37:34" }, { "name": "symfony/finder", @@ -1915,7 +1914,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" + "time": "2018-01-03 07:37:34" }, { "name": "symfony/polyfill-mbstring", @@ -1974,7 +1973,7 @@ "portable", "shim" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-01-30 19:27:44" }, { "name": "symfony/process", @@ -2023,29 +2022,29 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-01-29T08:54:45+00:00" + "time": "2018-01-29 08:54:45" }, { "name": "tedivm/jshrink", - "version": "v1.1.0", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/tedious/JShrink.git", - "reference": "688527a2e854d7935f24f24c7d5eb1b604742bf9" + "reference": "68ce379b213741e86f02bf6053b0d26b9f833448" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tedious/JShrink/zipball/688527a2e854d7935f24f24c7d5eb1b604742bf9", - "reference": "688527a2e854d7935f24f24c7d5eb1b604742bf9", + "url": "https://api.github.com/repos/tedious/JShrink/zipball/68ce379b213741e86f02bf6053b0d26b9f833448", + "reference": "68ce379b213741e86f02bf6053b0d26b9f833448", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": "^5.6|^7.0" }, "require-dev": { - "fabpot/php-cs-fixer": "0.4.0", - "phpunit/phpunit": "4.0.*", - "satooshi/php-coveralls": "dev-master" + "friendsofphp/php-cs-fixer": "^2.8", + "php-coveralls/php-coveralls": "^1.1.0", + "phpunit/phpunit": "^6" }, "type": "library", "autoload": { @@ -2069,20 +2068,20 @@ "javascript", "minifier" ], - "time": "2015-07-04T07:35:09+00:00" + "time": "2017-12-08 00:59:56" }, { "name": "tubalmartin/cssmin", - "version": "v4.1.0", + "version": "v4.1.1", "source": { "type": "git", "url": "https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port.git", - "reference": "1c7ae93cf6b392d4dae5c4ae18979918413af16e" + "reference": "3cbf557f4079d83a06f9c3ff9b957c022d7805cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tubalmartin/YUI-CSS-compressor-PHP-port/zipball/1c7ae93cf6b392d4dae5c4ae18979918413af16e", - "reference": "1c7ae93cf6b392d4dae5c4ae18979918413af16e", + "url": "https://api.github.com/repos/tubalmartin/YUI-CSS-compressor-PHP-port/zipball/3cbf557f4079d83a06f9c3ff9b957c022d7805cf", + "reference": "3cbf557f4079d83a06f9c3ff9b957c022d7805cf", "shasum": "" }, "require": { @@ -2122,7 +2121,7 @@ "minify", "yui" ], - "time": "2017-05-16T13:45:26+00:00" + "time": "2018-01-15 15:26:51" }, { "name": "webonyx/graphql-php", @@ -2169,7 +2168,7 @@ "api", "graphql" ], - "time": "2017-12-12T09:03:21+00:00" + "time": "2017-12-12 09:03:21" }, { "name": "zendframework/zend-captcha", @@ -2226,7 +2225,7 @@ "captcha", "zf2" ], - "time": "2017-02-23T08:09:44+00:00" + "time": "2017-02-23 08:09:44" }, { "name": "zendframework/zend-code", @@ -2279,7 +2278,7 @@ "code", "zf2" ], - "time": "2016-10-24T13:23:32+00:00" + "time": "2016-10-24 13:23:32" }, { "name": "zendframework/zend-config", @@ -2335,7 +2334,7 @@ "config", "zf2" ], - "time": "2016-02-04T23:01:10+00:00" + "time": "2016-02-04 23:01:10" }, { "name": "zendframework/zend-console", @@ -2388,7 +2387,7 @@ "console", "zf" ], - "time": "2018-01-25T19:08:04+00:00" + "time": "2018-01-25 19:08:04" }, { "name": "zendframework/zend-crypt", @@ -2438,7 +2437,7 @@ "crypt", "zf2" ], - "time": "2016-02-03T23:46:30+00:00" + "time": "2016-02-03 23:46:30" }, { "name": "zendframework/zend-db", @@ -2496,7 +2495,7 @@ "db", "zf" ], - "time": "2017-12-11T14:57:52+00:00" + "time": "2017-12-11 14:57:52" }, { "name": "zendframework/zend-di", @@ -2543,7 +2542,7 @@ "di", "zf2" ], - "time": "2016-04-25T20:58:11+00:00" + "time": "2016-04-25 20:58:11" }, { "name": "zendframework/zend-escaper", @@ -2587,7 +2586,7 @@ "escaper", "zf2" ], - "time": "2016-06-30T19:48:38+00:00" + "time": "2016-06-30 19:48:38" }, { "name": "zendframework/zend-eventmanager", @@ -2634,7 +2633,7 @@ "eventmanager", "zf2" ], - "time": "2017-12-12T17:48:56+00:00" + "time": "2017-12-12 17:48:56" }, { "name": "zendframework/zend-feed", @@ -2695,7 +2694,7 @@ "feed", "zf" ], - "time": "2017-12-04T17:59:38+00:00" + "time": "2017-12-04 17:59:38" }, { "name": "zendframework/zend-filter", @@ -2755,7 +2754,7 @@ "filter", "zf2" ], - "time": "2017-05-17T20:56:17+00:00" + "time": "2017-05-17 20:56:17" }, { "name": "zendframework/zend-form", @@ -2833,7 +2832,7 @@ "form", "zf" ], - "time": "2017-12-06T21:09:08+00:00" + "time": "2017-12-06 21:09:08" }, { "name": "zendframework/zend-http", @@ -2886,7 +2885,7 @@ "zend", "zf" ], - "time": "2017-10-13T12:06:24+00:00" + "time": "2017-10-13 12:06:24" }, { "name": "zendframework/zend-hydrator", @@ -2944,7 +2943,7 @@ "hydrator", "zf2" ], - "time": "2016-02-18T22:38:26+00:00" + "time": "2016-02-18 22:38:26" }, { "name": "zendframework/zend-i18n", @@ -3011,7 +3010,7 @@ "i18n", "zf2" ], - "time": "2017-05-17T17:00:12+00:00" + "time": "2017-05-17 17:00:12" }, { "name": "zendframework/zend-inputfilter", @@ -3064,7 +3063,7 @@ "inputfilter", "zf" ], - "time": "2018-01-22T19:41:18+00:00" + "time": "2018-01-22 19:41:18" }, { "name": "zendframework/zend-json", @@ -3119,7 +3118,7 @@ "json", "zf2" ], - "time": "2016-02-04T21:20:26+00:00" + "time": "2016-02-04 21:20:26" }, { "name": "zendframework/zend-loader", @@ -3163,7 +3162,7 @@ "loader", "zf2" ], - "time": "2015-06-03T14:05:47+00:00" + "time": "2015-06-03 14:05:47" }, { "name": "zendframework/zend-log", @@ -3234,7 +3233,7 @@ "logging", "zf2" ], - "time": "2017-05-17T16:03:26+00:00" + "time": "2017-05-17 16:03:26" }, { "name": "zendframework/zend-mail", @@ -3296,7 +3295,7 @@ "mail", "zf2" ], - "time": "2017-06-08T20:03:58+00:00" + "time": "2017-06-08 20:03:58" }, { "name": "zendframework/zend-math", @@ -3346,7 +3345,7 @@ "math", "zf2" ], - "time": "2016-04-07T16:29:53+00:00" + "time": "2016-04-07 16:29:53" }, { "name": "zendframework/zend-mime", @@ -3397,7 +3396,7 @@ "mime", "zf" ], - "time": "2017-11-28T15:02:22+00:00" + "time": "2017-11-28 15:02:22" }, { "name": "zendframework/zend-modulemanager", @@ -3457,7 +3456,7 @@ "modulemanager", "zf" ], - "time": "2017-12-02T06:11:18+00:00" + "time": "2017-12-02 06:11:18" }, { "name": "zendframework/zend-mvc", @@ -3544,7 +3543,7 @@ "mvc", "zf2" ], - "time": "2016-02-23T15:24:59+00:00" + "time": "2016-02-23 15:24:59" }, { "name": "zendframework/zend-serializer", @@ -3602,7 +3601,7 @@ "serializer", "zf2" ], - "time": "2017-11-20T22:21:04+00:00" + "time": "2017-11-20 22:21:04" }, { "name": "zendframework/zend-server", @@ -3648,7 +3647,7 @@ "server", "zf2" ], - "time": "2016-06-20T22:27:55+00:00" + "time": "2016-06-20 22:27:55" }, { "name": "zendframework/zend-servicemanager", @@ -3700,7 +3699,7 @@ "servicemanager", "zf2" ], - "time": "2017-12-05T16:27:36+00:00" + "time": "2017-12-05 16:27:36" }, { "name": "zendframework/zend-session", @@ -3770,7 +3769,7 @@ "session", "zf" ], - "time": "2018-01-31T17:38:47+00:00" + "time": "2018-01-31 17:38:47" }, { "name": "zendframework/zend-soap", @@ -3823,7 +3822,7 @@ "soap", "zf2" ], - "time": "2018-01-29T17:51:26+00:00" + "time": "2018-01-29 17:51:26" }, { "name": "zendframework/zend-stdlib", @@ -3882,7 +3881,7 @@ "stdlib", "zf2" ], - "time": "2016-04-12T21:17:31+00:00" + "time": "2016-04-12 21:17:31" }, { "name": "zendframework/zend-text", @@ -3929,7 +3928,7 @@ "text", "zf2" ], - "time": "2016-02-08T19:03:52+00:00" + "time": "2016-02-08 19:03:52" }, { "name": "zendframework/zend-uri", @@ -3976,7 +3975,7 @@ "uri", "zf2" ], - "time": "2016-02-17T22:38:51+00:00" + "time": "2016-02-17 22:38:51" }, { "name": "zendframework/zend-validator", @@ -4047,7 +4046,7 @@ "validator", "zf2" ], - "time": "2018-02-01T17:05:33+00:00" + "time": "2018-02-01 17:05:33" }, { "name": "zendframework/zend-view", @@ -4134,7 +4133,7 @@ "view", "zf2" ], - "time": "2018-01-17T22:21:50+00:00" + "time": "2018-01-17 22:21:50" } ], "packages-dev": [ @@ -4190,7 +4189,7 @@ "constructor", "instantiate" ], - "time": "2015-06-14T21:17:01+00:00" + "time": "2015-06-14 21:17:01" }, { "name": "friendsofphp/php-cs-fixer", @@ -4260,7 +4259,7 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2017-03-31T12:59:38+00:00" + "time": "2017-03-31 12:59:38" }, { "name": "ircmaxell/password-compat", @@ -4302,7 +4301,7 @@ "hashing", "password" ], - "time": "2014-11-20T16:49:30+00:00" + "time": "2014-11-20 16:49:30" }, { "name": "lusitanian/oauth", @@ -4369,7 +4368,7 @@ "oauth", "security" ], - "time": "2016-07-12T22:15:40+00:00" + "time": "2016-07-12 22:15:40" }, { "name": "myclabs/deep-copy", @@ -4414,30 +4413,30 @@ "object", "object graph" ], - "time": "2017-10-19T19:58:43+00:00" + "time": "2017-10-19 19:58:43" }, { "name": "pdepend/pdepend", - "version": "2.5.0", + "version": "2.5.2", "source": { "type": "git", "url": "https://github.com/pdepend/pdepend.git", - "reference": "0c50874333149c0dad5a2877801aed148f2767ff" + "reference": "9daf26d0368d4a12bed1cacae1a9f3a6f0adf239" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdepend/pdepend/zipball/0c50874333149c0dad5a2877801aed148f2767ff", - "reference": "0c50874333149c0dad5a2877801aed148f2767ff", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/9daf26d0368d4a12bed1cacae1a9f3a6f0adf239", + "reference": "9daf26d0368d4a12bed1cacae1a9f3a6f0adf239", "shasum": "" }, "require": { "php": ">=5.3.7", - "symfony/config": "^2.3.0|^3", - "symfony/dependency-injection": "^2.3.0|^3", - "symfony/filesystem": "^2.3.0|^3" + "symfony/config": "^2.3.0|^3|^4", + "symfony/dependency-injection": "^2.3.0|^3|^4", + "symfony/filesystem": "^2.3.0|^3|^4" }, "require-dev": { - "phpunit/phpunit": "^4.4.0,<4.8", + "phpunit/phpunit": "^4.8|^5.7", "squizlabs/php_codesniffer": "^2.0.0" }, "bin": [ @@ -4454,7 +4453,7 @@ "BSD-3-Clause" ], "description": "Official version of pdepend to be handled with Composer", - "time": "2017-01-19T14:23:36+00:00" + "time": "2017-12-13 13:21:38" }, { "name": "phar-io/manifest", @@ -4509,7 +4508,7 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" + "time": "2017-03-05 18:14:27" }, { "name": "phar-io/version", @@ -4556,7 +4555,7 @@ } ], "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" + "time": "2017-03-05 17:38:23" }, { "name": "phpdocumentor/reflection-common", @@ -4610,7 +4609,7 @@ "reflection", "static analysis" ], - "time": "2017-09-11T18:02:19+00:00" + "time": "2017-09-11 18:02:19" }, { "name": "phpdocumentor/reflection-docblock", @@ -4661,7 +4660,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-30T07:14:17+00:00" + "time": "2017-11-30 07:14:17" }, { "name": "phpdocumentor/type-resolver", @@ -4708,7 +4707,7 @@ "email": "me@mikevanriel.com" } ], - "time": "2017-07-14T14:27:02+00:00" + "time": "2017-07-14 14:27:02" }, { "name": "phpmd/phpmd", @@ -4774,7 +4773,7 @@ "phpmd", "pmd" ], - "time": "2017-01-20T14:41:10+00:00" + "time": "2017-01-20 14:41:10" }, { "name": "phpspec/prophecy", @@ -4837,7 +4836,7 @@ "spy", "stub" ], - "time": "2017-11-24T13:59:53+00:00" + "time": "2017-11-24 13:59:53" }, { "name": "phpunit/php-code-coverage", @@ -4900,7 +4899,7 @@ "testing", "xunit" ], - "time": "2017-12-06T09:29:45+00:00" + "time": "2017-12-06 09:29:45" }, { "name": "phpunit/php-file-iterator", @@ -4947,7 +4946,7 @@ "filesystem", "iterator" ], - "time": "2017-11-27T13:52:08+00:00" + "time": "2017-11-27 13:52:08" }, { "name": "phpunit/php-text-template", @@ -4988,7 +4987,7 @@ "keywords": [ "template" ], - "time": "2015-06-21T13:50:34+00:00" + "time": "2015-06-21 13:50:34" }, { "name": "phpunit/php-timer", @@ -5037,7 +5036,7 @@ "keywords": [ "timer" ], - "time": "2017-02-26T11:10:40+00:00" + "time": "2017-02-26 11:10:40" }, { "name": "phpunit/php-token-stream", @@ -5086,7 +5085,7 @@ "keywords": [ "tokenizer" ], - "time": "2017-11-27T05:48:46+00:00" + "time": "2017-11-27 05:48:46" }, { "name": "phpunit/phpunit", @@ -5170,7 +5169,7 @@ "testing", "xunit" ], - "time": "2017-08-03T13:59:28+00:00" + "time": "2017-08-03 13:59:28" }, { "name": "phpunit/phpunit-mock-objects", @@ -5229,7 +5228,7 @@ "mock", "xunit" ], - "time": "2017-08-03T14:08:16+00:00" + "time": "2017-08-03 14:08:16" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -5274,7 +5273,7 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" + "time": "2017-03-04 06:30:41" }, { "name": "sebastian/comparator", @@ -5338,7 +5337,7 @@ "compare", "equality" ], - "time": "2017-03-03T06:26:08+00:00" + "time": "2017-03-03 06:26:08" }, { "name": "sebastian/diff", @@ -5390,7 +5389,7 @@ "keywords": [ "diff" ], - "time": "2017-05-22T07:24:03+00:00" + "time": "2017-05-22 07:24:03" }, { "name": "sebastian/environment", @@ -5440,7 +5439,7 @@ "environment", "hhvm" ], - "time": "2017-07-01T08:51:00+00:00" + "time": "2017-07-01 08:51:00" }, { "name": "sebastian/exporter", @@ -5507,7 +5506,7 @@ "export", "exporter" ], - "time": "2017-04-03T13:19:02+00:00" + "time": "2017-04-03 13:19:02" }, { "name": "sebastian/finder-facade", @@ -5546,7 +5545,7 @@ ], "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", "homepage": "https://github.com/sebastianbergmann/finder-facade", - "time": "2017-11-18T17:31:49+00:00" + "time": "2017-11-18 17:31:49" }, { "name": "sebastian/global-state", @@ -5597,7 +5596,7 @@ "keywords": [ "global state" ], - "time": "2017-04-27T15:39:26+00:00" + "time": "2017-04-27 15:39:26" }, { "name": "sebastian/object-enumerator", @@ -5644,7 +5643,7 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" + "time": "2017-08-03 12:35:26" }, { "name": "sebastian/object-reflector", @@ -5689,7 +5688,7 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" + "time": "2017-03-29 09:07:27" }, { "name": "sebastian/phpcpd", @@ -5740,7 +5739,7 @@ ], "description": "Copy/Paste Detector (CPD) for PHP code.", "homepage": "https://github.com/sebastianbergmann/phpcpd", - "time": "2016-04-17T19:32:49+00:00" + "time": "2016-04-17 19:32:49" }, { "name": "sebastian/recursion-context", @@ -5793,7 +5792,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" + "time": "2017-03-03 06:23:57" }, { "name": "sebastian/resource-operations", @@ -5835,7 +5834,7 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" + "time": "2015-07-28 20:34:47" }, { "name": "sebastian/version", @@ -5878,20 +5877,20 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" + "time": "2016-10-03 07:35:21" }, { "name": "squizlabs/php_codesniffer", - "version": "3.0.1", + "version": "3.2.2", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "f9eaf037edf22fdfccf04cb0ab57ebcb1e166219" + "reference": "d7c00c3000ac0ce79c96fcbfef86b49a71158cd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/f9eaf037edf22fdfccf04cb0ab57ebcb1e166219", - "reference": "f9eaf037edf22fdfccf04cb0ab57ebcb1e166219", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d7c00c3000ac0ce79c96fcbfef86b49a71158cd1", + "reference": "d7c00c3000ac0ce79c96fcbfef86b49a71158cd1", "shasum": "" }, "require": { @@ -5901,7 +5900,7 @@ "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0" }, "bin": [ "bin/phpcs", @@ -5929,7 +5928,7 @@ "phpcs", "standards" ], - "time": "2017-06-14T01:23:49+00:00" + "time": "2017-12-19 21:44:46" }, { "name": "symfony/config", @@ -5991,7 +5990,7 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2018-01-21T19:05:02+00:00" + "time": "2018-01-21 19:05:02" }, { "name": "symfony/dependency-injection", @@ -6062,7 +6061,7 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2018-01-29T09:16:57+00:00" + "time": "2018-01-29 09:16:57" }, { "name": "symfony/polyfill-php54", @@ -6120,7 +6119,7 @@ "portable", "shim" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-01-30 19:27:44" }, { "name": "symfony/polyfill-php55", @@ -6176,7 +6175,7 @@ "portable", "shim" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-01-30 19:27:44" }, { "name": "symfony/polyfill-php70", @@ -6235,7 +6234,7 @@ "portable", "shim" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-01-30 19:27:44" }, { "name": "symfony/polyfill-php72", @@ -6290,7 +6289,7 @@ "portable", "shim" ], - "time": "2018-01-31T17:43:24+00:00" + "time": "2018-01-31 17:43:24" }, { "name": "symfony/polyfill-xml", @@ -6338,7 +6337,7 @@ "portable", "shim" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-01-30 19:27:44" }, { "name": "symfony/stopwatch", @@ -6387,7 +6386,7 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" + "time": "2018-01-03 07:37:34" }, { "name": "theseer/fdomdocument", @@ -6427,7 +6426,7 @@ ], "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", "homepage": "https://github.com/theseer/fDOMDocument", - "time": "2017-06-30T11:53:12+00:00" + "time": "2017-06-30 11:53:12" }, { "name": "theseer/tokenizer", @@ -6467,7 +6466,7 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2017-04-07T12:08:54+00:00" + "time": "2017-04-07 12:08:54" }, { "name": "webmozart/assert", @@ -6517,7 +6516,7 @@ "check", "validate" ], - "time": "2018-01-29T19:49:41+00:00" + "time": "2018-01-29 19:49:41" } ], "aliases": [], From eb59db5fff13c3753807d24e969dd9060daeeddc Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 21 Mar 2018 11:20:38 -0500 Subject: [PATCH 132/668] MAGETWO-89260: Fix Travis build issues - fix integration tests and static test --- .../testsuite/Magento/Test/Bootstrap/EnvironmentTest.php | 2 +- .../Magento/Framework/Session/SaveHandlerTest.php | 5 ----- .../Magento/Framework/Image/Adapter/AbstractAdapter.php | 7 +++++-- lib/internal/Magento/Framework/Session/SaveHandler.php | 3 +-- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php index 9bd4ef6bf37a7..2d56212ae443a 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php @@ -77,4 +77,4 @@ public function testEmulateSession() $this->assertSame($sessionVars, $this->_getSessionVars(), 'Super-global $_SESSION must not be affected.'); $this->assertNotEmpty(session_id(), 'Global session identified has to be emulated.'); } -} \ No newline at end of file +} diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php index 690ae05d75988..d2c73dff1e03a 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php @@ -7,7 +7,6 @@ use Magento\Framework\App\DeploymentConfig; use Magento\Framework\Session\Config\ConfigInterface; -use Magento\Framework\Session\SaveHandler; use Magento\Framework\App\ObjectManager; class SaveHandlerTest extends \PHPUnit\Framework\TestCase @@ -55,10 +54,6 @@ public function testSetSaveHandler($deploymentConfigHandler, $iniHandler) $expected, ObjectManager::getInstance()->get(ConfigInterface::class)->getOption('session.save_handler') ); - - if ($iniHandler && isset($this->originalSaveHandler) && $iniHandler != $this->originalSaveHandler) { - ini_set('session.save_handler', $this->originalSaveHandler); - } } public function saveHandlerProvider() diff --git a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php index a32561704d178..6042e4eee491d 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php +++ b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php @@ -301,9 +301,12 @@ public function getImageType() if ($this->_fileType) { return $this->_fileType; } else { - list($this->_imageSrcWidth, $this->_imageSrcHeight, $this->_fileType) = getimagesize($this->_fileName); - return $this->_fileType; + if ($this->_canProcess()) { + list($this->_imageSrcWidth, $this->_imageSrcHeight, $this->_fileType) = getimagesize($this->_fileName); + return $this->_fileType; + } } + return null; } /** diff --git a/lib/internal/Magento/Framework/Session/SaveHandler.php b/lib/internal/Magento/Framework/Session/SaveHandler.php index 4ab3d8e28f169..74c6fc8215e34 100644 --- a/lib/internal/Magento/Framework/Session/SaveHandler.php +++ b/lib/internal/Magento/Framework/Session/SaveHandler.php @@ -7,7 +7,6 @@ use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\ObjectManager; -use Magento\Framework\Exception\SessionException; use Magento\Framework\Session\Config\ConfigInterface; /** @@ -53,7 +52,7 @@ public function __construct( try { $connection = $saveHandlerFactory->create($saveMethod); - } catch (SessionException $e) { + } catch (\LogicException $e) { $connection = $saveHandlerFactory->create($default); $this->setSaveHandler($default); } From 458d34ed2fd7f02d21f9eacb683f5298a31117c8 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 21 Mar 2018 11:25:08 -0500 Subject: [PATCH 133/668] MAGETWO-89292: Implement SDL from prototype - supporting not overwriting empty descriptions --- .../Magento/CatalogGraphQl/etc/schema.graphql | 4 ++-- .../MetaReader/FieldMetaReader.php | 12 +++++++--- .../MetaReader/TypeMetaReader.php | 9 ++++---- .../Config/GraphQlReader/Reader/EnumType.php | 22 +++++++++++-------- .../GraphQlReader/Reader/InputObjectType.php | 7 ++++-- .../GraphQlReader/Reader/InterfaceType.php | 7 ++++-- .../GraphQlReader/Reader/ObjectType.php | 2 +- 7 files changed, 40 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphql b/app/code/Magento/CatalogGraphQl/etc/schema.graphql index 8676dc37a397d..74019b7efdecb 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphql +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphql @@ -503,9 +503,9 @@ type Products @doc(description:"Comment for Products") { total_count: Int } -input ProductFilterInput { +input ProductFilterInput @doc(description:"Comment for ProductFilterInput") { name: FilterTypeInput - sku: FilterTypeInput + sku: FilterTypeInput @doc(description:"Comment for sku") description: FilterTypeInput short_description: FilterTypeInput price: FilterTypeInput diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php index e859301b99f00..d6c656b5e4fbf 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php @@ -46,7 +46,10 @@ public function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMet ); if (!empty($fieldMeta->astNode->directives) && !($fieldMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $result['description'] = $this->readTypeDescription($fieldMeta); + $description = $this->readTypeDescription($fieldMeta); + if ($description) { + $result['description'] = $description; + } } $arguments = $fieldMeta->args; @@ -62,7 +65,10 @@ public function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMet ); if (!empty($argumentMeta->astNode->directives) && !($argumentMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $result['arguments'][$argumentName]['description'] = $this->readTypeDescription($argumentMeta); + $description = $this->readTypeDescription($argumentMeta); + if ($description) { + $result['arguments'][$argumentName]['description'] = $description; + } } } return $result; @@ -101,7 +107,7 @@ private function readTypeDescription($meta) : string foreach ($directives as $directive) { if ($directive->name->value == 'doc') { foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'description') { + if ($directiveArgument->name->value == 'description' && $directiveArgument->value->value) { return $directiveArgument->value->value; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php index af37995d4d889..76a973489099c 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php @@ -21,7 +21,10 @@ public function readTypeMeta($meta, $parameterType = 'Argument') : array $result = []; if (!empty($meta->astNode->directives) && !($meta instanceof \GraphQL\Type\Definition\ScalarType)) { - $result['description'] = $this->readTypeDescription($meta); + $description = $this->readTypeDescription($meta); + if ($description) { + $result['description'] = $description; + } } if ($meta instanceof \GraphQL\Type\Definition\NonNull) { @@ -38,7 +41,6 @@ public function readTypeMeta($meta, $parameterType = 'Argument') : array } else { $result['itemsRequired'] = false; } - //$result['description'] = $itemTypeMeta->description; $itemTypeName = $itemTypeMeta->name; $result['itemType'] = $itemTypeName; if ($this->isScalarType((string)$itemTypeMeta)) { @@ -47,7 +49,6 @@ public function readTypeMeta($meta, $parameterType = 'Argument') : array $result['type'] = 'ObjectArray' . $parameterType; } } else { - //$result['description'] = $meta->description; $result['type'] = $meta->name; } @@ -78,7 +79,7 @@ private function readTypeDescription($meta) : string foreach ($directives as $directive) { if ($directive->name->value == 'doc') { foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'description') { + if ($directiveArgument->name->value == 'description' && $directiveArgument->value->value) { return $directiveArgument->value->value; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php index a4053cba5fb3b..6a1afe36fe912 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php @@ -23,21 +23,25 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array 'items' => [] // Populated later ]; foreach ($typeMeta->getValues() as $value) { - $description = ''; - if (!empty($value->astNode->directives)) { - $description = $this->readTypeDescription($value); - } - // TODO: Simplify structure, currently name is lost during conversion to GraphQL schema $result['items'][$value->value] = [ 'name' => strtolower($value->name), - '_value' => $value->value, - 'description' => $description + '_value' => $value->value ]; + + if (!empty($value->astNode->directives)) { + $description = $this->readTypeDescription($value); + if ($description) { + $result['items'][$value->value]['description'] = $description; + } + } } if (!empty($typeMeta->astNode->directives) && !($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $result['description'] = $this->readTypeDescription($typeMeta); + $description = $this->readTypeDescription($typeMeta); + if ($description) { + $result['description'] = $description; + } } return $result; @@ -59,7 +63,7 @@ private function readTypeDescription($meta) : string foreach ($directives as $directive) { if ($directive->name->value == 'doc') { foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'description') { + if ($directiveArgument->name->value == 'description' && $directiveArgument->value->value) { return $directiveArgument->value->value; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php index b815f1a7cf9a9..481ddcde685fc 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php @@ -65,7 +65,10 @@ private function readInputObjectFieldMeta(\GraphQL\Type\Definition\InputObjectFi $result = array_merge($result, $this->typeMetaReader->readTypeMeta($typeMeta, 'InputField')); if (!empty($fieldMeta->astNode->directives) && !($fieldMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $result['description'] = $this->readTypeDescription($fieldMeta); + $description = $this->readTypeDescription($fieldMeta); + if ($description) { + $result['description'] = $description; + } } return $result; @@ -84,7 +87,7 @@ private function readTypeDescription($meta) : string foreach ($directives as $directive) { if ($directive->name->value == 'doc') { foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'description') { + if ($directiveArgument->name->value == 'description' && $directiveArgument->value->value) { return $directiveArgument->value->value; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php index db3ee795a6c98..72d1bee4a475c 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php @@ -50,7 +50,10 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array } if (!empty($typeMeta->astNode->directives) && !($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $result['description'] = $this->readTypeDescription($typeMeta); + $description = $this->readTypeDescription($typeMeta); + if ($description) { + $result['description'] = $description; + } } return $result; @@ -94,7 +97,7 @@ private function readTypeDescription($meta) : string foreach ($directives as $directive) { if ($directive->name->value == 'doc') { foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'description') { + if ($directiveArgument->name->value == 'description' && $directiveArgument->value->value) { return $directiveArgument->value->value; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php index d15b2759ccc24..ede160b4b8e31 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php @@ -75,7 +75,7 @@ private function readTypeDescription($meta) : string foreach ($directives as $directive) { if ($directive->name->value == 'doc') { foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'description') { + if ($directiveArgument->name->value == 'description' && $directiveArgument->value->value) { return $directiveArgument->value->value; } } From dead48788afd4b803059e08c13ee77a258799986 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Wed, 21 Mar 2018 13:12:34 -0500 Subject: [PATCH 134/668] MAGETWO-89082: Update composer dependencies --- .../Framework/Encryption/Test/Unit/CryptTest.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php b/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php index 55a078aaade7d..91e3ecc67ac59 100644 --- a/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php +++ b/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php @@ -111,8 +111,18 @@ public function getConstructorExceptionData() $tooShortInitVector = str_repeat('-', $this->_getInitVectorSize($cipher, $mode) - 1); $tooLongInitVector = str_repeat('-', $this->_getInitVectorSize($cipher, $mode) + 1); $result['tooLongKey-' . $cipher . '-' . $mode . '-false'] = [$tooLongKey, $cipher, $mode, false]; - $result['key-' . $cipher . '-' . $mode . '-tooShortInitVector'] = [$this->_key, $cipher, $mode, $tooShortInitVector]; - $result['key-' . $cipher . '-' . $mode . '-tooLongInitVector'] = [$this->_key, $cipher, $mode, $tooLongInitVector]; + $result['key-' . $cipher . '-' . $mode . '-tooShortInitVector'] = [ + $this->_key, + $cipher, + $mode, + $tooShortInitVector + ]; + $result['key-' . $cipher . '-' . $mode . '-tooLongInitVector'] = [ + $this->_key, + $cipher, + $mode, + $tooLongInitVector + ]; } } return $result; From 9c3da40c79711e4ac9f62b8efa199c8d9136ed6b Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Wed, 21 Mar 2018 13:31:43 -0500 Subject: [PATCH 135/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - moved preference to be loaded earlier in the process --- app/code/Magento/WebapiAsync/etc/di.xml | 6 ++---- app/etc/di.xml | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/WebapiAsync/etc/di.xml b/app/code/Magento/WebapiAsync/etc/di.xml index 954c703c8a8b5..3903f1e3487f3 100755 --- a/app/code/Magento/WebapiAsync/etc/di.xml +++ b/app/code/Magento/WebapiAsync/etc/di.xml @@ -7,19 +7,17 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - - <preference for="Magento\WebapiAsync\Model\ConfigInterface" type="Magento\WebapiAsync\Model\Config" /> <preference for="Magento\WebapiAsync\Api\Data\AsyncResponseInterface" type="Magento\WebapiAsync\Model\AsyncResponse" /> <preference for="Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterface" type="Magento\WebapiAsync\Model\AsyncResponse\ItemStatus" /> <preference for="Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface" type="Magento\WebapiAsync\Model\AsyncResponse\ItemsList" /> - <type name="Magento\Framework\MessageQueue\MergerFactory"> + <!--type name="Magento\Framework\MessageQueue\MergerFactory"> <arguments> <argument name="mergers" xsi:type="array"> <item name="async.#" xsi:type="string">Magento\WebapiAsync\Model\Merger</item> </argument> </arguments> - </type> + </type--> <virtualType name="Magento\WebapiAsync\VirtualType\PublisherPool" type="Magento\Framework\MessageQueue\PublisherPool"> <arguments> diff --git a/app/etc/di.xml b/app/etc/di.xml index 012f4fec7bfad..a7bf241fd8a1f 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -218,13 +218,12 @@ <argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument> </arguments> </type> + <preference for="Magento\WebapiAsync\Model\ConfigInterface" type="Magento\WebapiAsync\Model\Config" /> <type name="Magento\Framework\Communication\Config\CompositeReader"> <arguments> <argument name="readers" xsi:type="array"> <item name="asyncServiceReader" xsi:type="array"> - <item name="reader" xsi:type="object"> - Magento\WebapiAsync\Code\Generator\Config\RemoteServiceReader\Communication - </item> + <item name="reader" xsi:type="object">Magento\WebapiAsync\Code\Generator\Config\RemoteServiceReader\Communication</item> <item name="sortOrder" xsi:type="string">0</item> </item> <item name="xmlReader" xsi:type="array"> @@ -1608,6 +1607,7 @@ <item name="remoteServiceReader" xsi:type="object" sortOrder="10">Magento\Framework\MessageQueue\Publisher\Config\RemoteService\Reader</item> <item name="xmlReader" xsi:type="object" sortOrder="20">Magento\Framework\MessageQueue\Publisher\Config\Xml\Reader</item> <item name="envReader" xsi:type="object" sortOrder="30">Magento\Framework\MessageQueue\Publisher\Config\Env\Reader</item> + <item name="asyncServiceReader" xsi:type="object" sortOrder="0">Magento\WebapiAsync\Code\Generator\Config\RemoteServiceReader\Publisher</item> </argument> </arguments> </type> From 73c5b6a45d0df850471338d597c10fe388a1ea17 Mon Sep 17 00:00:00 2001 From: Ben Batschelet <bbatschelet@magento.com> Date: Wed, 21 Mar 2018 13:47:50 -0500 Subject: [PATCH 136/668] Fix incompatible calls to count() in unit and static tests --- app/code/Magento/Backend/Block/Menu.php | 2 +- .../Test/Integrity/Magento/Backend/ControllerAclTest.php | 2 +- .../Magento/Setup/Test/Unit/Module/I18n/Pack/GeneratorTest.php | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Backend/Block/Menu.php b/app/code/Magento/Backend/Block/Menu.php index 717edb8fe06fc..7d86497288a69 100644 --- a/app/code/Magento/Backend/Block/Menu.php +++ b/app/code/Magento/Backend/Block/Menu.php @@ -352,7 +352,7 @@ protected function _addSubMenu($menuItem, $level, $limit, $id = null) return $output; } $output .= '<div class="submenu"' . ($level == 0 && isset($id) ? ' aria-labelledby="' . $id . '"' : '') . '>'; - $colStops = null; + $colStops = []; if ($level == 0 && $limit) { $colStops = $this->_columnBrake($menuItem->getChildren(), $limit); $output .= '<strong class="submenu-title">' . $this->_getAnchorLabel($menuItem) . '</strong>'; diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php index 5e1cfa1106d7e..187cb9087013e 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php @@ -233,7 +233,7 @@ private function isItTest($relativeFilePath) private function getControllerPath($relativeFilePath) { if (preg_match('~(Magento\/.*Controller\/Adminhtml\/.*)\.php~', $relativeFilePath, $matches)) { - if (is_array($matches) && count($matches) === 2 && is_array($matches[1]) && count($matches[1]) >= 1) { + if (count($matches) === 2) { $partPath = $matches[1]; return $partPath; } diff --git a/setup/src/Magento/Setup/Test/Unit/Module/I18n/Pack/GeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Module/I18n/Pack/GeneratorTest.php index 3395596f399a3..e1688289493af 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/I18n/Pack/GeneratorTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/I18n/Pack/GeneratorTest.php @@ -102,6 +102,9 @@ public function testGenerateEmptyFile() ->method('load') ->with($dictionaryPath) ->will($this->returnValue($this->dictionaryMock)); + $this->dictionaryMock->expects($this->once()) + ->method('getPhrases') + ->will($this->returnValue([])); $this->_generator->generate($dictionaryPath, $localeString, $mode, $allowDuplicates); } From 70a33ca1b5ed74f872e6b58fd9c7e29f9ef45ad5 Mon Sep 17 00:00:00 2001 From: Jacob Brown <jacob@gnu.org> Date: Wed, 21 Mar 2018 14:20:48 -0500 Subject: [PATCH 137/668] MAGETWO-89389: updating a couple of the other composer.json files with updated dependency versions --- app/code/Magento/Braintree/composer.json | 2 +- lib/internal/Magento/Framework/composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Braintree/composer.json b/app/code/Magento/Braintree/composer.json index c14addf550dfb..fb7bbec517769 100644 --- a/app/code/Magento/Braintree/composer.json +++ b/app/code/Magento/Braintree/composer.json @@ -6,7 +6,7 @@ }, "require": { "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", - "braintree/braintree_php": "3.22.0", + "braintree/braintree_php": "3.28.0", "magento/framework": "100.3.*", "magento/magento-composer-installer": "*", "magento/module-catalog": "101.2.*", diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json index b442effe5ffda..2766cdf41d0ec 100644 --- a/lib/internal/Magento/Framework/composer.json +++ b/lib/internal/Magento/Framework/composer.json @@ -30,7 +30,7 @@ "oyejorge/less.php": "~1.7.0", "symfony/console": "~2.3, !=2.7.0", "symfony/process": "~2.1", - "tedivm/jshrink": "~1.1.0", + "tedivm/jshrink": "~1.3.0", "zendframework/zend-code": "^3.1.0", "zendframework/zend-crypt": "^2.6.0", "zendframework/zend-http": "^2.6.0", From 59084ee3583494fae0345a1dcfc84cc3cb8928b9 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 21 Mar 2018 14:46:26 -0500 Subject: [PATCH 138/668] MAGETWO-89292: Implement SDL from prototype - supporting more docs --- .../Magento/CatalogGraphQl/etc/schema.graphql | 11 ++++--- app/code/Magento/GraphQl/etc/schema.graphql | 4 +-- .../MetaReader/TypeMetaReader.php | 30 ------------------- .../GraphQlReader/Reader/InputObjectType.php | 7 +++++ .../GraphQlReader/Reader/ObjectType.php | 5 +++- .../GraphQl/Type/Input/InputObjectType.php | 3 +- 6 files changed, 20 insertions(+), 40 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphql b/app/code/Magento/CatalogGraphQl/etc/schema.graphql index 74019b7efdecb..5861387727663 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphql +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphql @@ -450,8 +450,7 @@ type VirtualProduct implements ProductInterface, CustomizableProductInterface { manufacturer: Int } -type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface -@doc(description: "comment for items[ProductInterface].") { +type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface @doc(description: "comment for SimpleProduct.") { id: Int name: String sku: String @@ -498,7 +497,7 @@ type SimpleProduct implements ProductInterface, PhysicalProductInterface, Custom } type Products @doc(description:"Comment for Products") { - items: [ProductInterface] @doc(description: "comment for items[ProductInterface].") + items: [ProductInterface] @doc(description: "comment for items[Products].") page_info: SearchResultPageInfo @doc(description: "comment for page_info.") total_count: Int } @@ -543,7 +542,7 @@ input ProductFilterInput @doc(description:"Comment for ProductFilterInput") { or: ProductFilterInput } -type ProductMediaGalleryEntriesContent @doc(description: "The number of products returned.") { +type ProductMediaGalleryEntriesContent @doc(description: "Comment for ProductMediaGalleryEntriesContent.") { base64_encoded_data: String type: String name: String @@ -558,14 +557,14 @@ type ProductMediaGalleryEntriesVideoContent { video_metadata: String } -input ProductSortInput @doc(description:"Input ProductSortInput") { +input ProductSortInput @doc(description:"Comment for Input ProductSortInput") { name: SortEnum @doc(description:"Name") sku: SortEnum description: SortEnum short_description: SortEnum price: SortEnum special_price: SortEnum - special_from_date: SortEnum + special_from_date: SortEnum @doc(description:"Comment for special_from_date") special_to_date: SortEnum weight: SortEnum manufacturer: SortEnum diff --git a/app/code/Magento/GraphQl/etc/schema.graphql b/app/code/Magento/GraphQl/etc/schema.graphql index d0fd735a81ccc..687305ddf04dd 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphql +++ b/app/code/Magento/GraphQl/etc/schema.graphql @@ -3,7 +3,7 @@ type Query { } input FilterTypeInput @doc(description:"Comment for FilterTypeInput") { - eq: String @doc(description:"Equal") + eq: String @doc(description:"comment for Equal") finset: [String] from: String gt: String @@ -29,6 +29,6 @@ type SearchResultPageInfo enum SortEnum @doc(description: "comment for SortEnum.") { - ASC @doc(description:"Ascending") + ASC @doc(description:"comment for Ascending") DESC } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php index 76a973489099c..36be1ad275ed8 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php @@ -19,14 +19,6 @@ class TypeMetaReader public function readTypeMeta($meta, $parameterType = 'Argument') : array { $result = []; - - if (!empty($meta->astNode->directives) && !($meta instanceof \GraphQL\Type\Definition\ScalarType)) { - $description = $this->readTypeDescription($meta); - if ($description) { - $result['description'] = $description; - } - } - if ($meta instanceof \GraphQL\Type\Definition\NonNull) { $result['required'] = true; $meta = $meta->getWrappedType(); @@ -65,26 +57,4 @@ private function isScalarType(string $type) : bool { return in_array($type, ['String', 'Int', 'Float', 'Boolean', 'ID']); } - - /** - * Read documentation annotation for a specific type - * - * @param $meta - * @return string - */ - private function readTypeDescription($meta) : string - { - /** @var \GraphQL\Language\AST\NodeList $directives */ - $directives = $meta->astNode->directives; - foreach ($directives as $directive) { - if ($directive->name->value == 'doc') { - foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'description' && $directiveArgument->value->value) { - return $directiveArgument->value->value; - } - } - } - } - return ''; - } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php index 481ddcde685fc..8278e4bd8070d 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php @@ -41,6 +41,13 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array foreach ($fields as $fieldName => $fieldMeta) { $result['fields'][$fieldName] = $this->readInputObjectFieldMeta($fieldMeta); } + + if (!empty($typeMeta->astNode->directives) && !($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { + $description = $this->readTypeDescription($typeMeta); + if ($description) { + $result['description'] = $description; + } + } return $result; } else { return null; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php index ede160b4b8e31..f35a007edec1d 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php @@ -53,7 +53,10 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array } if (!empty($typeMeta->astNode->directives) && !($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $result['description'] = $this->readTypeDescription($typeMeta); + $description = $this->readTypeDescription($typeMeta); + if ($description) { + $result['description'] = $description; + } } return $result; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php index 6b655fca7c113..1c142f68530b4 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php @@ -86,7 +86,8 @@ public function __construct( $config['fields'][$field->getName()] = [ 'name' => $field->getName(), - 'type' => $type + 'type' => $type, + 'description'=> $field->getDescription() ]; } parent::__construct($config); From 0ddac3a8beece1eb743a9c1ad3d1c94f3d71da29 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 21 Mar 2018 14:47:09 -0500 Subject: [PATCH 139/668] MAGETWO-89260: Fix Travis build issues --- setup/src/Magento/Setup/Module/I18n/Pack/Generator.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/src/Magento/Setup/Module/I18n/Pack/Generator.php b/setup/src/Magento/Setup/Module/I18n/Pack/Generator.php index 720fc351bea00..d1da0a16487a3 100644 --- a/setup/src/Magento/Setup/Module/I18n/Pack/Generator.php +++ b/setup/src/Magento/Setup/Module/I18n/Pack/Generator.php @@ -71,7 +71,8 @@ public function generate( $locale = $this->factory->createLocale($locale); $dictionary = $this->dictionaryLoader->load($dictionaryPath); - if (!count($dictionary->getPhrases())) { + $phrases = $dictionary->getPhrases(); + if (!is_array($phrases) || !count($phrases)) { throw new \UnexpectedValueException('No phrases have been found by the specified path.'); } From 117bcfc8b58ac88099672701578bd684130407f7 Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Wed, 21 Mar 2018 15:35:07 -0500 Subject: [PATCH 140/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - fixed static errors --- .../RemoteServiceReader/Communication.php | 1 + .../Config/RemoteServiceReader/Consumer.php | 1 + .../Config/RemoteServiceReader/Publisher.php | 1 + .../Config/RemoteServiceReader/Topology.php | 1 + .../Rest/AsynchronousRequestProcessor.php | 3 +- .../Model/MessageQueue/MassSchedule.php | 29 ++++--------------- app/code/Magento/WebapiAsync/etc/module.xml | 2 +- .../WebapiAsync/etc/webapi_rest/di.xml | 2 +- app/etc/di.xml | 2 +- 9 files changed, 14 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php index 1567e24a429d9..2e07e26fda8fb 100644 --- a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php @@ -45,6 +45,7 @@ public function __construct( * * @param string|null $scope * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function read($scope = null) { diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php index a34d90195477d..373ccc1041e43 100644 --- a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php @@ -34,6 +34,7 @@ public function __construct( * * @param string|null $scope * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function read($scope = null) { diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php index 13808bbbf1761..c221908efde19 100644 --- a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php @@ -35,6 +35,7 @@ public function __construct( * * @param string|null $scope * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function read($scope = null) { diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php index 917dd2ddeb74a..c6f2e36760a95 100644 --- a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php @@ -43,6 +43,7 @@ public function __construct( * * @param string|null $scope * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function read($scope = null) { diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php index e5feda6859bb2..ccc1303d92955 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php @@ -58,8 +58,7 @@ public function __construct( MassSchedule $asyncBulkPublisher, WebApiAsyncConfig $webapiAsyncConfig, DataObjectProcessor $dataObjectProcessor - ) - { + ) { $this->response = $response; $this->inputParamsResolver = $inputParamsResolver; $this->asyncBulkPublisher = $asyncBulkPublisher; diff --git a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php index 221a149a8c85d..3cb9be290738b 100644 --- a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php +++ b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php @@ -46,7 +46,7 @@ class MassSchedule /** * @var \Magento\Framework\Serialize\Serializer\Json */ - private $jsonHelper; + private $jsonSerializer; /** * @var \Magento\Framework\EntityManager\EntityManager @@ -68,16 +68,6 @@ class MassSchedule */ private $itemStatusInterfaceFactory; - /** - * @var BulkSummaryInterfaceFactory - */ - private $bulkSummaryFactory; - - /** - * @var \Psr\Log\LoggerInterface - */ - private $logger; - /** * @var MessageEncoder */ @@ -99,46 +89,39 @@ class MassSchedule * @param \Magento\AsynchronousOperations\Api\Data\OperationInterfaceFactory $operationFactory * @param \Magento\Framework\DataObject\IdentityGeneratorInterface $identityService * @param \Magento\Authorization\Model\UserContextInterface $userContextInterface - * @param \Magento\Framework\Serialize\Serializer\Json $jsonHelper + * @param \Magento\Framework\Serialize\Serializer\Json $jsonSerializer * @param \Magento\Framework\EntityManager\EntityManager $entityManager * @param \Magento\WebapiAsync\Api\Data\AsyncResponseInterfaceFactory $asyncResponse * @param \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterfaceFactory $itemsListFactory * @param \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterfaceFactory $itemStatusFactory - * @param \Magento\AsynchronousOperations\Api\Data\BulkSummaryInterfaceFactory $bulkSummaryFactory * @param \Magento\Framework\MessageQueue\MessageEncoder $messageEncoder * @param \Magento\Framework\MessageQueue\MessageValidator $messageValidator * @param \Magento\Framework\Bulk\BulkManagementInterface $bulkManagement - * @param \Psr\Log\LoggerInterface $logger */ public function __construct( OperationInterfaceFactory $operationFactory, IdentityGeneratorInterface $identityService, UserContextInterface $userContextInterface, - Json $jsonHelper, + Json $jsonSerializer, EntityManager $entityManager, AsyncResponseInterfaceFactory $asyncResponse, ItemsListInterfaceFactory $itemsListFactory, ItemStatusInterfaceFactory $itemStatusFactory, - BulkSummaryInterfaceFactory $bulkSummaryFactory, MessageEncoder $messageEncoder, MessageValidator $messageValidator, - BulkManagementInterface $bulkManagement, - LoggerInterface $logger + BulkManagementInterface $bulkManagement ) { $this->userContext = $userContextInterface; $this->operationFactory = $operationFactory; $this->identityService = $identityService; - $this->jsonHelper = $jsonHelper; + $this->jsonSerializer = $jsonSerializer; $this->entityManager = $entityManager; $this->asyncResponseFactory = $asyncResponse; $this->itemsListInterfaceFactory = $itemsListFactory; $this->itemStatusInterfaceFactory = $itemStatusFactory; - $this->bulkSummaryFactory = $bulkSummaryFactory; $this->messageEncoder = $messageEncoder; $this->messageValidator = $messageValidator; $this->bulkManagement = $bulkManagement; - - $this->logger = $logger ? : \Magento\Framework\App\ObjectManager::getInstance()->get(LoggerInterface::class); } /** @@ -192,7 +175,7 @@ public function publishMass($topicName, $entitiesArray, $groupId = null) 'data' => [ OperationInterface::BULK_ID => $groupId, OperationInterface::TOPIC_NAME => $topicName, - OperationInterface::SERIALIZED_DATA => $this->jsonHelper->serialize($serializedData), + OperationInterface::SERIALIZED_DATA => $this->jsonSerializer->serialize($serializedData), OperationInterface::STATUS => OperationInterface::STATUS_TYPE_OPEN, ], ]; diff --git a/app/code/Magento/WebapiAsync/etc/module.xml b/app/code/Magento/WebapiAsync/etc/module.xml index 3a77676805b70..abda4ff56aeac 100644 --- a/app/code/Magento/WebapiAsync/etc/module.xml +++ b/app/code/Magento/WebapiAsync/etc/module.xml @@ -1,7 +1,7 @@ <?xml version="1.0"?> <!-- /** - * Copyright © 2016 Magento. All rights reserved. + * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ --> diff --git a/app/code/Magento/WebapiAsync/etc/webapi_rest/di.xml b/app/code/Magento/WebapiAsync/etc/webapi_rest/di.xml index 86a4392723bbf..96f27158aac40 100644 --- a/app/code/Magento/WebapiAsync/etc/webapi_rest/di.xml +++ b/app/code/Magento/WebapiAsync/etc/webapi_rest/di.xml @@ -1,7 +1,7 @@ <?xml version="1.0"?> <!-- /** - * Copyright © 2016 Magento. All rights reserved. + * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ --> diff --git a/app/etc/di.xml b/app/etc/di.xml index a7bf241fd8a1f..5b7504f58b9ec 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -218,7 +218,7 @@ <argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument> </arguments> </type> - <preference for="Magento\WebapiAsync\Model\ConfigInterface" type="Magento\WebapiAsync\Model\Config" /> + <preference for="Magento\WebapiAsync\Model\ConfigInterface" type="Magento\WebapiAsync\Model\Config\Proxy" /> <type name="Magento\Framework\Communication\Config\CompositeReader"> <arguments> <argument name="readers" xsi:type="array"> From f8f65d39382394697678b08fbddc8e021e7f91bc Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 21 Mar 2018 16:39:26 -0500 Subject: [PATCH 141/668] MAGETWO-89292: Implement SDL from prototype - refactor supporting more docs --- .../Magento/CatalogGraphQl/etc/schema.graphql | 6 +- .../GraphQl/Config/GraphQlReader.php | 40 ++++++++----- .../GraphQlReader/MetaReader/DocReader.php | 34 +++++++++++ .../MetaReader/FieldMetaReader.php | 46 ++++----------- .../MetaReader/TypeMetaReader.php | 13 +--- .../Config/GraphQlReader/Reader/EnumType.php | 59 ++++++++----------- .../GraphQlReader/Reader/InputObjectType.php | 46 ++++----------- .../GraphQlReader/Reader/InterfaceType.php | 43 +++++--------- .../GraphQlReader/Reader/ObjectType.php | 43 +++++--------- 9 files changed, 142 insertions(+), 188 deletions(-) create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/DocReader.php diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphql b/app/code/Magento/CatalogGraphQl/etc/schema.graphql index 5861387727663..c2625890509e8 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphql +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphql @@ -254,7 +254,7 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") @doc(description: "comment for ProductInterface.") { - id: Int @doc(description: "comment for [ProductInterface].") + id: Int @doc(description: "comment for ProductInterface Id.") name: String sku: String description: String @@ -455,7 +455,7 @@ type SimpleProduct implements ProductInterface, PhysicalProductInterface, Custom name: String sku: String description: String - short_description: String + short_description: String @doc(description: "Comment for short_description.") special_price: Float special_from_date: String special_to_date: String @@ -497,7 +497,7 @@ type SimpleProduct implements ProductInterface, PhysicalProductInterface, Custom } type Products @doc(description:"Comment for Products") { - items: [ProductInterface] @doc(description: "comment for items[Products].") + items: [ProductInterface] @doc(description: "comment for items[ProductInterface] on Products.") page_info: SearchResultPageInfo @doc(description: "comment for page_info.") total_count: Int } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php index ea7a98e849e74..421c270dc01a3 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php @@ -69,23 +69,10 @@ public function read($scope = null) : array $knownTypes = []; foreach ($schemaFiles as $partialSchemaContent) { $partialSchemaTypes = $this->parseTypes($partialSchemaContent); - /** - * Keep declarations from current partial schema, add missing declarations from all previously read schemas - */ + // Keep declarations from current partial schema, add missing declarations from all previously read schemas $knownTypes = $partialSchemaTypes + $knownTypes; $schemaContent = implode("\n", $knownTypes); - $partialResult = []; - $schema = \GraphQL\Utils\BuildSchema::build($schemaContent); - $typeMap = $schema->getTypeMap(); - foreach ($typeMap as $typeName => $typeMeta) { - if ((strpos($typeName, '__') !== 0 && (!$typeMeta instanceof \GraphQL\Type\Definition\ScalarType))) { - // Skip built-in object types - $partialResult[$typeName] = $this->typeReader->read($typeMeta); - if (!$partialResult[$typeName]) { - throw new \LogicException("'{$typeName}' cannot be processed."); - } - } - } + $partialResult = $this->readPartialTypes($schemaContent); $result = array_replace_recursive($result, $partialResult); } @@ -93,6 +80,29 @@ public function read($scope = null) : array return $result; } + + /** + * Extract types as string from schema as string + * + * @param string $graphQlSchemaContent + * @return string[] [$typeName => $typeDeclaration, ...] + */ + private function readPartialTypes(string $graphQlSchemaContent) : array + { + $partialResult = []; + $schema = \GraphQL\Utils\BuildSchema::build($graphQlSchemaContent); + foreach ($schema->getTypeMap() as $typeName => $typeMeta) { + // Only process custom types and skip built-in object types + if ((strpos($typeName, '__') !== 0 && (!$typeMeta instanceof \GraphQL\Type\Definition\ScalarType))) { + $partialResult[$typeName] = $this->typeReader->read($typeMeta); + if (!$partialResult[$typeName]) { + throw new \LogicException("'{$typeName}' cannot be processed."); + } + } + } + return $partialResult; + } + /** * Extract types as string from a larger string that represents the graphql schema using regular expressions * diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/DocReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/DocReader.php new file mode 100644 index 0000000000000..bff4634ca5afa --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/DocReader.php @@ -0,0 +1,34 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader; + +/** + * Reads documentation from a AST node + */ +class DocReader +{ + /** + * Read documentation annotation for a specific node if exists + * + * @param \GraphQL\Language\AST\NodeList $directives + * @return string|null + */ + public function readTypeDescription(\GraphQL\Language\AST\NodeList $directives) : ?string + { + foreach ($directives as $directive) { + if ($directive->name->value == 'doc') { + foreach ($directive->arguments as $directiveArgument) { + if ($directiveArgument->name->value == 'description') { + return $directiveArgument->value->value; + } + } + } + } + return null; + } +} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php index d6c656b5e4fbf..c96d7c9e9346a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php @@ -14,12 +14,19 @@ class FieldMetaReader */ private $typeMetaReader; + /** + * @var DocReader + */ + private $docReader; + /** * @param TypeMetaReader $typeMetaReader + * @param DocReader $docReader */ - public function __construct(TypeMetaReader $typeMetaReader) + public function __construct(TypeMetaReader $typeMetaReader, DocReader $docReader) { $this->typeMetaReader = $typeMetaReader; + $this->docReader = $docReader; } /** @@ -45,11 +52,8 @@ public function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMet $this->typeMetaReader->readTypeMeta($fieldTypeMeta, 'OutputField') ); - if (!empty($fieldMeta->astNode->directives) && !($fieldMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $description = $this->readTypeDescription($fieldMeta); - if ($description) { - $result['description'] = $description; - } + if ($this->docReader->readTypeDescription($fieldMeta->astNode->directives)) { + $result['description'] = $this->docReader->readTypeDescription($fieldMeta->astNode->directives); } $arguments = $fieldMeta->args; @@ -64,11 +68,9 @@ public function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMet $this->typeMetaReader->readTypeMeta($typeMeta, 'Argument') ); - if (!empty($argumentMeta->astNode->directives) && !($argumentMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $description = $this->readTypeDescription($argumentMeta); - if ($description) { - $result['arguments'][$argumentName]['description'] = $description; - } + if ($this->docReader->readTypeDescription($argumentMeta->astNode->directives)) { + $result['arguments'][$argumentName]['description'] = + $this->docReader->readTypeDescription($argumentMeta->astNode->directives); } } return $result; @@ -93,26 +95,4 @@ private function readFieldResolver(\GraphQL\Type\Definition\FieldDefinition $fie } return null; } - - /** - * Read documentation annotation for a specific type - * - * @param $meta - * @return string - */ - private function readTypeDescription($meta) : string - { - /** @var \GraphQL\Language\AST\NodeList $directives */ - $directives = $meta->astNode->directives; - foreach ($directives as $directive) { - if ($directive->name->value == 'doc') { - foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'description' && $directiveArgument->value->value) { - return $directiveArgument->value->value; - } - } - } - } - return ''; - } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php index 36be1ad275ed8..a42e781808991 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php @@ -35,7 +35,7 @@ public function readTypeMeta($meta, $parameterType = 'Argument') : array } $itemTypeName = $itemTypeMeta->name; $result['itemType'] = $itemTypeName; - if ($this->isScalarType((string)$itemTypeMeta)) { + if ($itemTypeMeta instanceof \GraphQL\Type\Definition\ScalarType) { $result['type'] = 'ScalarArray' . $parameterType; } else { $result['type'] = 'ObjectArray' . $parameterType; @@ -46,15 +46,4 @@ public function readTypeMeta($meta, $parameterType = 'Argument') : array return $result; } - - /** - * Test if type is a scalar type - * - * @param string $type - * @return bool - */ - private function isScalarType(string $type) : bool - { - return in_array($type, ['String', 'Int', 'Float', 'Boolean', 'ID']); - } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php index 6a1afe36fe912..c682c0eeb116f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php @@ -8,9 +8,23 @@ namespace Magento\Framework\GraphQl\Config\GraphQlReader\Reader; use Magento\Framework\GraphQl\Config\GraphQlReader\TypeMetaReaderInterface; +use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\DocReader; class EnumType implements TypeMetaReaderInterface { + /** + * @var DocReader + */ + private $docReader; + + /** + * @param DocReader $docReader + */ + public function __construct(DocReader $docReader) + { + $this->docReader = $docReader; + } + /** * {@inheritdoc} */ @@ -22,26 +36,21 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array 'type' => 'graphql_enum', 'items' => [] // Populated later ]; - foreach ($typeMeta->getValues() as $value) { + foreach ($typeMeta->getValues() as $enumValueMeta) { // TODO: Simplify structure, currently name is lost during conversion to GraphQL schema - $result['items'][$value->value] = [ - 'name' => strtolower($value->name), - '_value' => $value->value + $result['items'][$enumValueMeta->value] = [ + 'name' => strtolower($enumValueMeta->name), + '_value' => $enumValueMeta->value ]; - if (!empty($value->astNode->directives)) { - $description = $this->readTypeDescription($value); - if ($description) { - $result['items'][$value->value]['description'] = $description; - } + if ($this->docReader->readTypeDescription($enumValueMeta->astNode->directives)) { + $result['items'][$enumValueMeta->value]['description'] = + $this->docReader->readTypeDescription($enumValueMeta->astNode->directives); } } - if (!empty($typeMeta->astNode->directives) && !($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $description = $this->readTypeDescription($typeMeta); - if ($description) { - $result['description'] = $description; - } + if ($this->docReader->readTypeDescription($typeMeta->astNode->directives)) { + $result['description'] = $this->docReader->readTypeDescription($typeMeta->astNode->directives); } return $result; @@ -49,26 +58,4 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array return null; } } - - /** - * Read documentation annotation for a specific type - * - * @param $meta - * @return string - */ - private function readTypeDescription($meta) : string - { - /** @var \GraphQL\Language\AST\NodeList $directives */ - $directives = $meta->astNode->directives; - foreach ($directives as $directive) { - if ($directive->name->value == 'doc') { - foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'description' && $directiveArgument->value->value) { - return $directiveArgument->value->value; - } - } - } - } - return ''; - } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php index 8278e4bd8070d..7f45e1d84dafb 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php @@ -9,6 +9,7 @@ use Magento\Framework\GraphQl\Config\GraphQlReader\TypeMetaReaderInterface; use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\TypeMetaReader; +use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\DocReader; class InputObjectType implements TypeMetaReaderInterface { @@ -17,12 +18,19 @@ class InputObjectType implements TypeMetaReaderInterface */ private $typeMetaReader; + /** + * @var DocReader + */ + private $docReader; + /** * @param TypeMetaReader $typeMetaReader + * @param DocReader $docReader */ - public function __construct(TypeMetaReader $typeMetaReader) + public function __construct(TypeMetaReader $typeMetaReader, DocReader $docReader) { $this->typeMetaReader = $typeMetaReader; + $this->docReader = $docReader; } /** @@ -42,11 +50,8 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array $result['fields'][$fieldName] = $this->readInputObjectFieldMeta($fieldMeta); } - if (!empty($typeMeta->astNode->directives) && !($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $description = $this->readTypeDescription($typeMeta); - if ($description) { - $result['description'] = $description; - } + if ($this->docReader->readTypeDescription($typeMeta->astNode->directives)) { + $result['description'] = $this->docReader->readTypeDescription($typeMeta->astNode->directives); } return $result; } else { @@ -71,35 +76,10 @@ private function readInputObjectFieldMeta(\GraphQL\Type\Definition\InputObjectFi $result = array_merge($result, $this->typeMetaReader->readTypeMeta($typeMeta, 'InputField')); - if (!empty($fieldMeta->astNode->directives) && !($fieldMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $description = $this->readTypeDescription($fieldMeta); - if ($description) { - $result['description'] = $description; - } + if ($this->docReader->readTypeDescription($fieldMeta->astNode->directives)) { + $result['description'] = $this->docReader->readTypeDescription($fieldMeta->astNode->directives); } return $result; } - - /** - * Read documentation annotation for a specific type - * - * @param $meta - * @return string - */ - private function readTypeDescription($meta) : string - { - /** @var \GraphQL\Language\AST\NodeList $directives */ - $directives = $meta->astNode->directives; - foreach ($directives as $directive) { - if ($directive->name->value == 'doc') { - foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'description' && $directiveArgument->value->value) { - return $directiveArgument->value->value; - } - } - } - } - return ''; - } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php index 72d1bee4a475c..3b4d0a6ffaf51 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php @@ -9,6 +9,7 @@ use Magento\Framework\GraphQl\Config\GraphQlReader\TypeMetaReaderInterface; use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\FieldMetaReader; +use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\DocReader; class InterfaceType implements TypeMetaReaderInterface { @@ -17,12 +18,19 @@ class InterfaceType implements TypeMetaReaderInterface */ private $fieldMetaReader; + /** + * @var DocReader + */ + private $docReader; + /** * @param FieldMetaReader $fieldMetaReader + * @param DocReader $docReader */ - public function __construct(FieldMetaReader $fieldMetaReader) + public function __construct(FieldMetaReader $fieldMetaReader, DocReader $docReader) { $this->fieldMetaReader = $fieldMetaReader; + $this->docReader = $docReader; } /** @@ -49,11 +57,12 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array $result['fields'][$fieldName] = $this->fieldMetaReader->readFieldMeta($fieldMeta); } - if (!empty($typeMeta->astNode->directives) && !($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $description = $this->readTypeDescription($typeMeta); - if ($description) { - $result['description'] = $description; - } + if ( ($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { + $x=1; + } + + if ($this->docReader->readTypeDescription($typeMeta->astNode->directives)) { + $result['description'] = $this->docReader->readTypeDescription($typeMeta->astNode->directives); } return $result; @@ -83,26 +92,4 @@ private function getInterfaceTypeResolver(\GraphQL\Type\Definition\InterfaceType } return null; } - - /** - * Read documentation annotation for a specific type - * - * @param $meta - * @return string - */ - private function readTypeDescription($meta) : string - { - /** @var \GraphQL\Language\AST\NodeList $directives */ - $directives = $meta->astNode->directives; - foreach ($directives as $directive) { - if ($directive->name->value == 'doc') { - foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'description' && $directiveArgument->value->value) { - return $directiveArgument->value->value; - } - } - } - } - return ''; - } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php index f35a007edec1d..a762ee3770c72 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php @@ -9,6 +9,7 @@ use Magento\Framework\GraphQl\Config\GraphQlReader\TypeMetaReaderInterface; use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\FieldMetaReader; +use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\DocReader; class ObjectType implements TypeMetaReaderInterface { @@ -17,12 +18,19 @@ class ObjectType implements TypeMetaReaderInterface */ private $fieldMetaReader; + /** + * @var DocReader + */ + private $docReader; + /** * @param FieldMetaReader $fieldMetaReader + * @param DocReader $docReader */ - public function __construct(FieldMetaReader $fieldMetaReader) + public function __construct(FieldMetaReader $fieldMetaReader, DocReader $docReader) { $this->fieldMetaReader = $fieldMetaReader; + $this->docReader = $docReader; } /** @@ -52,11 +60,12 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array $result['fields'][$fieldName] = $this->fieldMetaReader->readFieldMeta($fieldMeta); } - if (!empty($typeMeta->astNode->directives) && !($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $description = $this->readTypeDescription($typeMeta); - if ($description) { - $result['description'] = $description; - } + if ( ($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { + $x=1; + } + + if ($this->docReader->readTypeDescription($typeMeta->astNode->directives)) { + $result['description'] = $this->docReader->readTypeDescription($typeMeta->astNode->directives); } return $result; @@ -64,26 +73,4 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array return null; } } - - /** - * Read documentation annotation for a specific type - * - * @param $meta - * @return string - */ - private function readTypeDescription($meta) : string - { - /** @var \GraphQL\Language\AST\NodeList $directives */ - $directives = $meta->astNode->directives; - foreach ($directives as $directive) { - if ($directive->name->value == 'doc') { - foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'description' && $directiveArgument->value->value) { - return $directiveArgument->value->value; - } - } - } - } - return ''; - } } From 93417de7a125c15302346db8117114b208433985 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 21 Mar 2018 16:46:29 -0500 Subject: [PATCH 142/668] MAGETWO-89292: Implement SDL from prototype - refactor supporting more docs --- .../Magento/CatalogGraphQl/etc/schema.graphql | 39 ++++++++----------- app/code/Magento/GraphQl/etc/schema.graphql | 19 ++++----- .../GraphQl/Config/GraphQlReader.php | 3 ++ 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphql b/app/code/Magento/CatalogGraphQl/etc/schema.graphql index c2625890509e8..c897a8559c69f 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphql +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphql @@ -1,13 +1,12 @@ type Query { products( - search: String @doc(description: "comment for search."), + search: String, filter: ProductFilterInput, pageSize: Int, currentPage: Int, sort: ProductSortInput ): Products @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") - @doc(description: "comment for products.") } enum CurrencyEnum { @@ -250,11 +249,8 @@ type ProductTierPrices { website_id: Float } -interface ProductInterface -@typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") -@doc(description: "comment for ProductInterface.") -{ - id: Int @doc(description: "comment for ProductInterface Id.") +interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") { + id: Int name: String sku: String description: String @@ -450,12 +446,13 @@ type VirtualProduct implements ProductInterface, CustomizableProductInterface { manufacturer: Int } -type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface @doc(description: "comment for SimpleProduct.") { +type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface +{ id: Int name: String sku: String description: String - short_description: String @doc(description: "Comment for short_description.") + short_description: String special_price: Float special_from_date: String special_to_date: String @@ -496,15 +493,15 @@ type SimpleProduct implements ProductInterface, PhysicalProductInterface, Custom manufacturer: Int } -type Products @doc(description:"Comment for Products") { - items: [ProductInterface] @doc(description: "comment for items[ProductInterface] on Products.") - page_info: SearchResultPageInfo @doc(description: "comment for page_info.") +type Products { + items: [ProductInterface] + page_info: SearchResultPageInfo total_count: Int } -input ProductFilterInput @doc(description:"Comment for ProductFilterInput") { +input ProductFilterInput { name: FilterTypeInput - sku: FilterTypeInput @doc(description:"Comment for sku") + sku: FilterTypeInput description: FilterTypeInput short_description: FilterTypeInput price: FilterTypeInput @@ -542,7 +539,7 @@ input ProductFilterInput @doc(description:"Comment for ProductFilterInput") { or: ProductFilterInput } -type ProductMediaGalleryEntriesContent @doc(description: "Comment for ProductMediaGalleryEntriesContent.") { +type ProductMediaGalleryEntriesContent { base64_encoded_data: String type: String name: String @@ -557,14 +554,14 @@ type ProductMediaGalleryEntriesVideoContent { video_metadata: String } -input ProductSortInput @doc(description:"Comment for Input ProductSortInput") { - name: SortEnum @doc(description:"Name") +input ProductSortInput { + name: SortEnum sku: SortEnum description: SortEnum short_description: SortEnum price: SortEnum special_price: SortEnum - special_from_date: SortEnum @doc(description:"Comment for special_from_date") + special_from_date: SortEnum special_to_date: SortEnum weight: SortEnum manufacturer: SortEnum @@ -596,10 +593,8 @@ input ProductSortInput @doc(description:"Comment for Input ProductSortInput") { gift_message_available: SortEnum } -type MediaGalleryEntry -@doc(description: "comment for MediaGalleryEntry") -{ - id: Int @doc(description: "id for MediaGalleryEntry") +type MediaGalleryEntry { + id: Int media_type: String label: String position: Int diff --git a/app/code/Magento/GraphQl/etc/schema.graphql b/app/code/Magento/GraphQl/etc/schema.graphql index 687305ddf04dd..498da368074fb 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphql +++ b/app/code/Magento/GraphQl/etc/schema.graphql @@ -1,9 +1,9 @@ type Query { - placeholder: String @doc(description: "comment for placeholder.") + placeholder: String } -input FilterTypeInput @doc(description:"Comment for FilterTypeInput") { - eq: String @doc(description:"comment for Equal") +input FilterTypeInput { + eq: String finset: [String] from: String gt: String @@ -20,15 +20,12 @@ input FilterTypeInput @doc(description:"Comment for FilterTypeInput") { nin: [String] } -type SearchResultPageInfo -@doc(description:"Comment for SearchResultPageInfo") -{ - page_size: Int @doc(description:"Comment for page_size") - current_page: Int @doc(description:"Comment for current_page") +type SearchResultPageInfo { + page_size: Int + current_page: Int } -enum SortEnum @doc(description: "comment for SortEnum.") -{ - ASC @doc(description:"comment for Ascending") +enum SortEnum { + ASC DESC } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php index 421c270dc01a3..09a2054c2976e 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php @@ -54,6 +54,9 @@ public function __construct( $this->fileName = $fileName; } + /** + * {@inheritdoc} + */ public function read($scope = null) : array { $result = []; From b67f8392dd879876ca04bca86bdfead9bcb4f05f Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 21 Mar 2018 16:49:58 -0500 Subject: [PATCH 143/668] MAGETWO-89292: Implement SDL from prototype - refactor supporting more docs --- .../GraphQl/Config/GraphQlReader/Reader/InterfaceType.php | 4 ---- .../GraphQl/Config/GraphQlReader/Reader/ObjectType.php | 4 ---- 2 files changed, 8 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php index 3b4d0a6ffaf51..00299a5463158 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php @@ -57,10 +57,6 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array $result['fields'][$fieldName] = $this->fieldMetaReader->readFieldMeta($fieldMeta); } - if ( ($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $x=1; - } - if ($this->docReader->readTypeDescription($typeMeta->astNode->directives)) { $result['description'] = $this->docReader->readTypeDescription($typeMeta->astNode->directives); } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php index a762ee3770c72..fa7b364f4b5fe 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php @@ -60,10 +60,6 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array $result['fields'][$fieldName] = $this->fieldMetaReader->readFieldMeta($fieldMeta); } - if ( ($typeMeta instanceof \GraphQL\Type\Definition\ScalarType)) { - $x=1; - } - if ($this->docReader->readTypeDescription($typeMeta->astNode->directives)) { $result['description'] = $this->docReader->readTypeDescription($typeMeta->astNode->directives); } From eb393b146a1db64f94321bfebc1f98833c6abb25 Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Wed, 21 Mar 2018 17:43:10 -0500 Subject: [PATCH 144/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - add proxies for the queue commands --- app/code/Magento/MessageQueue/etc/di.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/MessageQueue/etc/di.xml b/app/code/Magento/MessageQueue/etc/di.xml index de9d2b0269367..c8f2edb862613 100644 --- a/app/code/Magento/MessageQueue/etc/di.xml +++ b/app/code/Magento/MessageQueue/etc/di.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <preference for="Magento\Framework\MessageQueue\ConfigInterface" type="Magento\Framework\MessageQueue\Config" /> + <preference for="Magento\Framework\MessageQueue\ConfigInterface" type="Magento\Framework\MessageQueue\Config\Proxy" /> <preference for="Magento\Framework\MessageQueue\LockInterface" type="Magento\Framework\MessageQueue\Lock" /> <preference for="Magento\Framework\MessageQueue\Lock\WriterInterface" type="Magento\MessageQueue\Model\ResourceModel\Lock" /> <preference for="Magento\Framework\MessageQueue\Lock\ReaderInterface" type="Magento\MessageQueue\Model\ResourceModel\Lock" /> @@ -16,8 +16,8 @@ <type name="Magento\Framework\Console\CommandListInterface"> <arguments> <argument name="commands" xsi:type="array"> - <item name="startConsumerCommand" xsi:type="object">Magento\MessageQueue\Console\StartConsumerCommand</item> - <item name="consumerListCommand" xsi:type="object">Magento\MessageQueue\Console\ConsumerListCommand</item> + <item name="startConsumerCommand" xsi:type="object">Magento\MessageQueue\Console\StartConsumerCommand\Proxy</item> + <item name="consumerListCommand" xsi:type="object">Magento\MessageQueue\Console\ConsumerListCommand\Proxy</item> </argument> </arguments> </type> From adfba245daf5362672d13e95dc193908684d0086 Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Wed, 21 Mar 2018 17:50:08 -0500 Subject: [PATCH 145/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - fixed di.xml --- app/etc/di.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/etc/di.xml b/app/etc/di.xml index 5b7504f58b9ec..0d9392063397d 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -1607,7 +1607,6 @@ <item name="remoteServiceReader" xsi:type="object" sortOrder="10">Magento\Framework\MessageQueue\Publisher\Config\RemoteService\Reader</item> <item name="xmlReader" xsi:type="object" sortOrder="20">Magento\Framework\MessageQueue\Publisher\Config\Xml\Reader</item> <item name="envReader" xsi:type="object" sortOrder="30">Magento\Framework\MessageQueue\Publisher\Config\Env\Reader</item> - <item name="asyncServiceReader" xsi:type="object" sortOrder="0">Magento\WebapiAsync\Code\Generator\Config\RemoteServiceReader\Publisher</item> </argument> </arguments> </type> From d5d8d54af81a6f6e80df50ec4e8025c263eb4de1 Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Wed, 21 Mar 2018 17:55:34 -0500 Subject: [PATCH 146/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - Asynchronous schema processor class must implement interface --- .../Rest/AsynchronousSchemaRequestProcessor.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessor.php b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessor.php index 497496e1af6f4..1da14ac9c6b20 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessor.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessor.php @@ -62,10 +62,13 @@ public function process(\Magento\Framework\Webapi\Rest\Request $request) } /** - * {@inheritdoc} + * {@inheritdoc} */ - public function getProcessorPath() + public function canProcess(\Magento\Framework\Webapi\Rest\Request $request) { - return self::PROCESSOR_PATH; + if (preg_match(self::PROCESSOR_PATH, ltrim($request->getPathInfo(), '/')) === 0) { + return true; + } + return false; } } From 28cf9671df3794a31784c4f24d47bb0be1d88b13 Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Wed, 21 Mar 2018 18:10:43 -0500 Subject: [PATCH 147/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - updated class namespace - updated config.json with the correct values - removed unused variables and methods --- .../Test/ApiFunctional/BulkScheduleTest.php | 90 ++----- app/code/Magento/WebapiAsync/composer.json | 3 - composer.json | 1 + composer.lock | 241 +++++++++--------- 4 files changed, 138 insertions(+), 197 deletions(-) diff --git a/app/code/Magento/WebapiAsync/Test/ApiFunctional/BulkScheduleTest.php b/app/code/Magento/WebapiAsync/Test/ApiFunctional/BulkScheduleTest.php index 3473f8fe5f120..29f0b299ce128 100644 --- a/app/code/Magento/WebapiAsync/Test/ApiFunctional/BulkScheduleTest.php +++ b/app/code/Magento/WebapiAsync/Test/ApiFunctional/BulkScheduleTest.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\WebapiAsync\Test\Async; +namespace Magento\WebapiAsync\Test\ApiFunctional; use Magento\Catalog\Api\Data\ProductInterface; use Magento\TestFramework\TestCase\WebapiAbstract; @@ -92,29 +92,6 @@ class BulkScheduleTest extends WebapiAbstract */ private $config; - /** - * @var \Magento\Framework\App\DeploymentConfig - */ - private $deploymentConfig; - - /** - * @var array - */ - private $productData = [ - [ - ProductInterface::SKU => 'simple', - ProductInterface::NAME => 'Simple Related Product', - ProductInterface::TYPE_ID => 'simple', - ProductInterface::PRICE => 10, - ], - [ - ProductInterface::SKU => 'simple_with_cross', - ProductInterface::NAME => 'Simple Product With Related Product', - ProductInterface::TYPE_ID => 'simple', - ProductInterface::PRICE => 10, - ], - ]; - /** * @inheritdoc */ @@ -138,20 +115,20 @@ protected function setUp() $this->config = $this->loadConfig(); $this->shellMock->expects($this->any()) - ->method('execute') - ->willReturnCallback(function ($command, $arguments) { - $command = vsprintf($command, $arguments); - $params = - \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams(); - $params['MAGE_DIRS']['base']['path'] = BP; - $params = - 'INTEGRATION_TEST_PARAMS="' . urldecode(http_build_query($params)) . '"'; - $command = - str_replace('bin/magento', 'dev/tests/integration/bin/magento', $command); - $command = $params . ' ' . $command; - - return exec("{$command} > /dev/null &"); - }); + ->method('execute') + ->willReturnCallback(function ($command, $arguments) { + $command = vsprintf($command, $arguments); + $params = + \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams(); + $params['MAGE_DIRS']['base']['path'] = BP; + $params = + 'INTEGRATION_TEST_PARAMS="' . urldecode(http_build_query($params)) . '"'; + $command = + str_replace('bin/magento', 'dev/tests/integration/bin/magento', $command); + $command = $params . ' ' . $command; + + return exec("{$command} > /dev/null &"); + }); } /** @@ -405,7 +382,7 @@ private function writeConfig(array $config) /** * @inheritdoc */ - private function tearDown() + protected function tearDown() { foreach ($this->consumerConfig->getConsumers() as $consumer) { $consumerName = $consumer->getName(); @@ -428,39 +405,4 @@ private function tearDown() $this->writeConfig($this->config); $this->appConfig->reinit(); } - - /** - * Mock AMQP configuration. - * - * @param bool $enabled - * @return void - */ - private function setAmqpConfiguredStatus($enabled) - { - if ($enabled) { - $data = [ - 'amqp' => - [ - 'host' => 'localhost', - 'port' => '5672', - 'user' => 'guest', - 'password' => 'guest', - 'virtualhost' => '/', - 'ssl' => '', - ], - ]; - } else { - $data = [ - 'amqp' => - [ - 'host' => '', - 'port' => '', - 'user' => '', - 'password' => '', - 'virtualhost' => '/', - 'ssl' => '', - ], - ]; - } - } } diff --git a/app/code/Magento/WebapiAsync/composer.json b/app/code/Magento/WebapiAsync/composer.json index 4424d52d64328..1ceaaac86daf7 100644 --- a/app/code/Magento/WebapiAsync/composer.json +++ b/app/code/Magento/WebapiAsync/composer.json @@ -8,9 +8,6 @@ "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", "magento/framework": "100.3.*", "magento/module-authorization": "100.3.*", - "magento/module-backend": "100.3.*", - "magento/module-integration": "100.3.*", - "magento/module-store": "100.3.*", "magento/module-webapi": "100.3.*", "magento/module-asynchronous-operations": "100.3.*" }, diff --git a/composer.json b/composer.json index 754be9fffec9a..661468f438bc6 100644 --- a/composer.json +++ b/composer.json @@ -220,6 +220,7 @@ "magento/module-vault": "100.3.0-dev", "magento/module-version": "100.3.0-dev", "magento/module-webapi": "100.3.0-dev", + "magento/module-webapi-async": "100.3.0-dev", "magento/module-webapi-security": "100.3.0-dev", "magento/module-weee": "100.3.0-dev", "magento/module-widget": "100.3.0-dev", diff --git a/composer.lock b/composer.lock index 7dc6b64f20be1..ddaafe79cb081 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "1052c147f8bf4c3a3c27b032aec1b9a5", + "hash": "bf103fd125d40bdeb82fd67bb34e46c0", + "content-hash": "de6c896a88703a9a9416cc7042892305", "packages": [ { "name": "braintree/braintree_php", @@ -51,7 +52,7 @@ } ], "description": "Braintree PHP Client Library", - "time": "2017-02-16T19:59:04+00:00" + "time": "2017-02-16 19:59:04" }, { "name": "colinmollenhour/cache-backend-file", @@ -87,7 +88,7 @@ ], "description": "The stock Zend_Cache_Backend_File backend has extremely poor performance for cleaning by tags making it become unusable as the number of cached items increases. This backend makes many changes resulting in a huge performance boost, especially for tag cleaning.", "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_File", - "time": "2016-05-02T16:24:47+00:00" + "time": "2016-05-02 16:24:47" }, { "name": "colinmollenhour/cache-backend-redis", @@ -123,7 +124,7 @@ ], "description": "Zend_Cache backend using Redis with full support for tags.", "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis", - "time": "2017-03-25T04:54:24+00:00" + "time": "2017-03-25 04:54:24" }, { "name": "colinmollenhour/credis", @@ -163,7 +164,7 @@ ], "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", "homepage": "https://github.com/colinmollenhour/credis", - "time": "2017-07-05T15:32:38+00:00" + "time": "2017-07-05 15:32:38" }, { "name": "colinmollenhour/php-redis-session-abstract", @@ -200,7 +201,7 @@ ], "description": "A Redis-based session handler with optimistic locking", "homepage": "https://github.com/colinmollenhour/php-redis-session-abstract", - "time": "2018-01-08T14:53:13+00:00" + "time": "2018-01-08 14:53:13" }, { "name": "composer/ca-bundle", @@ -256,7 +257,7 @@ "ssl", "tls" ], - "time": "2017-11-29T09:37:33+00:00" + "time": "2017-11-29 09:37:33" }, { "name": "composer/composer", @@ -333,7 +334,7 @@ "dependency", "package" ], - "time": "2017-03-10T08:29:45+00:00" + "time": "2017-03-10 08:29:45" }, { "name": "composer/semver", @@ -395,7 +396,7 @@ "validation", "versioning" ], - "time": "2016-08-30T16:08:34+00:00" + "time": "2016-08-30 16:08:34" }, { "name": "composer/spdx-licenses", @@ -456,7 +457,7 @@ "spdx", "validator" ], - "time": "2018-01-31T13:17:27+00:00" + "time": "2018-01-31 13:17:27" }, { "name": "container-interop/container-interop", @@ -487,7 +488,7 @@ ], "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", "homepage": "https://github.com/container-interop/container-interop", - "time": "2017-02-14T19:40:03+00:00" + "time": "2017-02-14 19:40:03" }, { "name": "elasticsearch/elasticsearch", @@ -542,7 +543,7 @@ "elasticsearch", "search" ], - "time": "2017-11-08T17:04:47+00:00" + "time": "2017-11-08 17:04:47" }, { "name": "guzzlehttp/ringphp", @@ -593,7 +594,7 @@ } ], "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.", - "time": "2015-05-20T03:37:09+00:00" + "time": "2015-05-20 03:37:09" }, { "name": "guzzlehttp/streams", @@ -643,7 +644,7 @@ "Guzzle", "stream" ], - "time": "2014-10-12T19:18:40+00:00" + "time": "2014-10-12 19:18:40" }, { "name": "justinrainbow/json-schema", @@ -709,7 +710,7 @@ "json", "schema" ], - "time": "2017-10-21T13:15:38+00:00" + "time": "2017-10-21 13:15:38" }, { "name": "magento/composer", @@ -745,7 +746,7 @@ "AFL-3.0" ], "description": "Magento composer library helps to instantiate Composer application and run composer commands.", - "time": "2017-04-24T09:57:02+00:00" + "time": "2017-04-24 09:57:02" }, { "name": "magento/magento-composer-installer", @@ -824,7 +825,7 @@ "composer-installer", "magento" ], - "time": "2017-12-29T16:45:24+00:00" + "time": "2017-12-29 16:45:24" }, { "name": "magento/zendframework1", @@ -871,7 +872,7 @@ "ZF1", "framework" ], - "time": "2017-06-21T14:56:23+00:00" + "time": "2017-06-21 14:56:23" }, { "name": "monolog/monolog", @@ -949,7 +950,7 @@ "logging", "psr-3" ], - "time": "2017-06-19T01:22:40+00:00" + "time": "2017-06-19 01:22:40" }, { "name": "oyejorge/less.php", @@ -1011,7 +1012,7 @@ "php", "stylesheet" ], - "time": "2017-03-28T22:19:25+00:00" + "time": "2017-03-28 22:19:25" }, { "name": "paragonie/random_compat", @@ -1059,7 +1060,7 @@ "pseudorandom", "random" ], - "time": "2017-09-27T21:40:39+00:00" + "time": "2017-09-27 21:40:39" }, { "name": "pelago/emogrifier", @@ -1128,7 +1129,7 @@ "email", "pre-processing" ], - "time": "2018-01-05T23:30:21+00:00" + "time": "2018-01-05 23:30:21" }, { "name": "php-amqplib/php-amqplib", @@ -1182,7 +1183,7 @@ "queue", "rabbitmq" ], - "time": "2015-08-11T12:30:09+00:00" + "time": "2015-08-11 12:30:09" }, { "name": "phpseclib/phpseclib", @@ -1274,7 +1275,7 @@ "x.509", "x509" ], - "time": "2017-11-29T06:38:08+00:00" + "time": "2017-11-29 06:38:08" }, { "name": "psr/container", @@ -1323,7 +1324,7 @@ "container-interop", "psr" ], - "time": "2017-02-14T16:28:37+00:00" + "time": "2017-02-14 16:28:37" }, { "name": "psr/log", @@ -1370,7 +1371,7 @@ "psr", "psr-3" ], - "time": "2016-10-10T12:19:37+00:00" + "time": "2016-10-10 12:19:37" }, { "name": "ramsey/uuid", @@ -1452,7 +1453,7 @@ "identifier", "uuid" ], - "time": "2017-03-26T20:37:53+00:00" + "time": "2017-03-26 20:37:53" }, { "name": "react/promise", @@ -1498,7 +1499,7 @@ "promise", "promises" ], - "time": "2017-03-25T12:08:31+00:00" + "time": "2017-03-25 12:08:31" }, { "name": "seld/cli-prompt", @@ -1546,7 +1547,7 @@ "input", "prompt" ], - "time": "2017-03-18T11:32:45+00:00" + "time": "2017-03-18 11:32:45" }, { "name": "seld/jsonlint", @@ -1595,7 +1596,7 @@ "parser", "validator" ], - "time": "2018-01-24T12:46:19+00:00" + "time": "2018-01-24 12:46:19" }, { "name": "seld/phar-utils", @@ -1639,7 +1640,7 @@ "keywords": [ "phra" ], - "time": "2015-10-13T18:44:15+00:00" + "time": "2015-10-13 18:44:15" }, { "name": "symfony/console", @@ -1700,7 +1701,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-01-29T08:54:45+00:00" + "time": "2018-01-29 08:54:45" }, { "name": "symfony/debug", @@ -1757,7 +1758,7 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2016-07-30T07:22:48+00:00" + "time": "2016-07-30 07:22:48" }, { "name": "symfony/event-dispatcher", @@ -1817,7 +1818,7 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:36:31+00:00" + "time": "2018-01-03 07:36:31" }, { "name": "symfony/filesystem", @@ -1866,7 +1867,7 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" + "time": "2018-01-03 07:37:34" }, { "name": "symfony/finder", @@ -1915,7 +1916,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" + "time": "2018-01-03 07:37:34" }, { "name": "symfony/polyfill-mbstring", @@ -1974,7 +1975,7 @@ "portable", "shim" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-01-30 19:27:44" }, { "name": "symfony/process", @@ -2023,7 +2024,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-01-29T08:54:45+00:00" + "time": "2018-01-29 08:54:45" }, { "name": "tedivm/jshrink", @@ -2069,7 +2070,7 @@ "javascript", "minifier" ], - "time": "2015-07-04T07:35:09+00:00" + "time": "2015-07-04 07:35:09" }, { "name": "tubalmartin/cssmin", @@ -2122,7 +2123,7 @@ "minify", "yui" ], - "time": "2017-05-16T13:45:26+00:00" + "time": "2017-05-16 13:45:26" }, { "name": "webonyx/graphql-php", @@ -2169,7 +2170,7 @@ "api", "graphql" ], - "time": "2017-12-12T09:03:21+00:00" + "time": "2017-12-12 09:03:21" }, { "name": "zendframework/zend-captcha", @@ -2226,7 +2227,7 @@ "captcha", "zf2" ], - "time": "2017-02-23T08:09:44+00:00" + "time": "2017-02-23 08:09:44" }, { "name": "zendframework/zend-code", @@ -2279,7 +2280,7 @@ "code", "zf2" ], - "time": "2016-10-24T13:23:32+00:00" + "time": "2016-10-24 13:23:32" }, { "name": "zendframework/zend-config", @@ -2335,7 +2336,7 @@ "config", "zf2" ], - "time": "2016-02-04T23:01:10+00:00" + "time": "2016-02-04 23:01:10" }, { "name": "zendframework/zend-console", @@ -2388,7 +2389,7 @@ "console", "zf" ], - "time": "2018-01-25T19:08:04+00:00" + "time": "2018-01-25 19:08:04" }, { "name": "zendframework/zend-crypt", @@ -2438,7 +2439,7 @@ "crypt", "zf2" ], - "time": "2016-02-03T23:46:30+00:00" + "time": "2016-02-03 23:46:30" }, { "name": "zendframework/zend-db", @@ -2496,7 +2497,7 @@ "db", "zf" ], - "time": "2017-12-11T14:57:52+00:00" + "time": "2017-12-11 14:57:52" }, { "name": "zendframework/zend-di", @@ -2543,7 +2544,7 @@ "di", "zf2" ], - "time": "2016-04-25T20:58:11+00:00" + "time": "2016-04-25 20:58:11" }, { "name": "zendframework/zend-escaper", @@ -2587,7 +2588,7 @@ "escaper", "zf2" ], - "time": "2016-06-30T19:48:38+00:00" + "time": "2016-06-30 19:48:38" }, { "name": "zendframework/zend-eventmanager", @@ -2634,7 +2635,7 @@ "eventmanager", "zf2" ], - "time": "2017-12-12T17:48:56+00:00" + "time": "2017-12-12 17:48:56" }, { "name": "zendframework/zend-feed", @@ -2695,7 +2696,7 @@ "feed", "zf" ], - "time": "2017-12-04T17:59:38+00:00" + "time": "2017-12-04 17:59:38" }, { "name": "zendframework/zend-filter", @@ -2755,7 +2756,7 @@ "filter", "zf2" ], - "time": "2017-05-17T20:56:17+00:00" + "time": "2017-05-17 20:56:17" }, { "name": "zendframework/zend-form", @@ -2833,7 +2834,7 @@ "form", "zf" ], - "time": "2017-12-06T21:09:08+00:00" + "time": "2017-12-06 21:09:08" }, { "name": "zendframework/zend-http", @@ -2886,7 +2887,7 @@ "zend", "zf" ], - "time": "2017-10-13T12:06:24+00:00" + "time": "2017-10-13 12:06:24" }, { "name": "zendframework/zend-hydrator", @@ -2944,7 +2945,7 @@ "hydrator", "zf2" ], - "time": "2016-02-18T22:38:26+00:00" + "time": "2016-02-18 22:38:26" }, { "name": "zendframework/zend-i18n", @@ -3011,7 +3012,7 @@ "i18n", "zf2" ], - "time": "2017-05-17T17:00:12+00:00" + "time": "2017-05-17 17:00:12" }, { "name": "zendframework/zend-inputfilter", @@ -3064,7 +3065,7 @@ "inputfilter", "zf" ], - "time": "2018-01-22T19:41:18+00:00" + "time": "2018-01-22 19:41:18" }, { "name": "zendframework/zend-json", @@ -3119,7 +3120,7 @@ "json", "zf2" ], - "time": "2016-02-04T21:20:26+00:00" + "time": "2016-02-04 21:20:26" }, { "name": "zendframework/zend-loader", @@ -3163,7 +3164,7 @@ "loader", "zf2" ], - "time": "2015-06-03T14:05:47+00:00" + "time": "2015-06-03 14:05:47" }, { "name": "zendframework/zend-log", @@ -3234,7 +3235,7 @@ "logging", "zf2" ], - "time": "2017-05-17T16:03:26+00:00" + "time": "2017-05-17 16:03:26" }, { "name": "zendframework/zend-mail", @@ -3296,7 +3297,7 @@ "mail", "zf2" ], - "time": "2017-06-08T20:03:58+00:00" + "time": "2017-06-08 20:03:58" }, { "name": "zendframework/zend-math", @@ -3346,7 +3347,7 @@ "math", "zf2" ], - "time": "2016-04-07T16:29:53+00:00" + "time": "2016-04-07 16:29:53" }, { "name": "zendframework/zend-mime", @@ -3397,7 +3398,7 @@ "mime", "zf" ], - "time": "2017-11-28T15:02:22+00:00" + "time": "2017-11-28 15:02:22" }, { "name": "zendframework/zend-modulemanager", @@ -3457,7 +3458,7 @@ "modulemanager", "zf" ], - "time": "2017-12-02T06:11:18+00:00" + "time": "2017-12-02 06:11:18" }, { "name": "zendframework/zend-mvc", @@ -3544,7 +3545,7 @@ "mvc", "zf2" ], - "time": "2016-02-23T15:24:59+00:00" + "time": "2016-02-23 15:24:59" }, { "name": "zendframework/zend-serializer", @@ -3602,7 +3603,7 @@ "serializer", "zf2" ], - "time": "2017-11-20T22:21:04+00:00" + "time": "2017-11-20 22:21:04" }, { "name": "zendframework/zend-server", @@ -3648,7 +3649,7 @@ "server", "zf2" ], - "time": "2016-06-20T22:27:55+00:00" + "time": "2016-06-20 22:27:55" }, { "name": "zendframework/zend-servicemanager", @@ -3700,7 +3701,7 @@ "servicemanager", "zf2" ], - "time": "2017-12-05T16:27:36+00:00" + "time": "2017-12-05 16:27:36" }, { "name": "zendframework/zend-session", @@ -3770,7 +3771,7 @@ "session", "zf" ], - "time": "2018-01-31T17:38:47+00:00" + "time": "2018-01-31 17:38:47" }, { "name": "zendframework/zend-soap", @@ -3823,7 +3824,7 @@ "soap", "zf2" ], - "time": "2018-01-29T17:51:26+00:00" + "time": "2018-01-29 17:51:26" }, { "name": "zendframework/zend-stdlib", @@ -3882,7 +3883,7 @@ "stdlib", "zf2" ], - "time": "2016-04-12T21:17:31+00:00" + "time": "2016-04-12 21:17:31" }, { "name": "zendframework/zend-text", @@ -3929,7 +3930,7 @@ "text", "zf2" ], - "time": "2016-02-08T19:03:52+00:00" + "time": "2016-02-08 19:03:52" }, { "name": "zendframework/zend-uri", @@ -3976,7 +3977,7 @@ "uri", "zf2" ], - "time": "2016-02-17T22:38:51+00:00" + "time": "2016-02-17 22:38:51" }, { "name": "zendframework/zend-validator", @@ -4047,7 +4048,7 @@ "validator", "zf2" ], - "time": "2018-02-01T17:05:33+00:00" + "time": "2018-02-01 17:05:33" }, { "name": "zendframework/zend-view", @@ -4134,7 +4135,7 @@ "view", "zf2" ], - "time": "2018-01-17T22:21:50+00:00" + "time": "2018-01-17 22:21:50" } ], "packages-dev": [ @@ -4190,7 +4191,7 @@ "constructor", "instantiate" ], - "time": "2015-06-14T21:17:01+00:00" + "time": "2015-06-14 21:17:01" }, { "name": "friendsofphp/php-cs-fixer", @@ -4260,7 +4261,7 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2017-03-31T12:59:38+00:00" + "time": "2017-03-31 12:59:38" }, { "name": "ircmaxell/password-compat", @@ -4302,7 +4303,7 @@ "hashing", "password" ], - "time": "2014-11-20T16:49:30+00:00" + "time": "2014-11-20 16:49:30" }, { "name": "lusitanian/oauth", @@ -4369,7 +4370,7 @@ "oauth", "security" ], - "time": "2016-07-12T22:15:40+00:00" + "time": "2016-07-12 22:15:40" }, { "name": "myclabs/deep-copy", @@ -4414,7 +4415,7 @@ "object", "object graph" ], - "time": "2017-10-19T19:58:43+00:00" + "time": "2017-10-19 19:58:43" }, { "name": "pdepend/pdepend", @@ -4454,7 +4455,7 @@ "BSD-3-Clause" ], "description": "Official version of pdepend to be handled with Composer", - "time": "2017-01-19T14:23:36+00:00" + "time": "2017-01-19 14:23:36" }, { "name": "phar-io/manifest", @@ -4509,7 +4510,7 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" + "time": "2017-03-05 18:14:27" }, { "name": "phar-io/version", @@ -4556,7 +4557,7 @@ } ], "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" + "time": "2017-03-05 17:38:23" }, { "name": "phpdocumentor/reflection-common", @@ -4610,7 +4611,7 @@ "reflection", "static analysis" ], - "time": "2017-09-11T18:02:19+00:00" + "time": "2017-09-11 18:02:19" }, { "name": "phpdocumentor/reflection-docblock", @@ -4661,7 +4662,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-30T07:14:17+00:00" + "time": "2017-11-30 07:14:17" }, { "name": "phpdocumentor/type-resolver", @@ -4708,7 +4709,7 @@ "email": "me@mikevanriel.com" } ], - "time": "2017-07-14T14:27:02+00:00" + "time": "2017-07-14 14:27:02" }, { "name": "phpmd/phpmd", @@ -4774,7 +4775,7 @@ "phpmd", "pmd" ], - "time": "2017-01-20T14:41:10+00:00" + "time": "2017-01-20 14:41:10" }, { "name": "phpspec/prophecy", @@ -4837,7 +4838,7 @@ "spy", "stub" ], - "time": "2017-11-24T13:59:53+00:00" + "time": "2017-11-24 13:59:53" }, { "name": "phpunit/php-code-coverage", @@ -4900,7 +4901,7 @@ "testing", "xunit" ], - "time": "2017-12-06T09:29:45+00:00" + "time": "2017-12-06 09:29:45" }, { "name": "phpunit/php-file-iterator", @@ -4947,7 +4948,7 @@ "filesystem", "iterator" ], - "time": "2017-11-27T13:52:08+00:00" + "time": "2017-11-27 13:52:08" }, { "name": "phpunit/php-text-template", @@ -4988,7 +4989,7 @@ "keywords": [ "template" ], - "time": "2015-06-21T13:50:34+00:00" + "time": "2015-06-21 13:50:34" }, { "name": "phpunit/php-timer", @@ -5037,7 +5038,7 @@ "keywords": [ "timer" ], - "time": "2017-02-26T11:10:40+00:00" + "time": "2017-02-26 11:10:40" }, { "name": "phpunit/php-token-stream", @@ -5086,7 +5087,7 @@ "keywords": [ "tokenizer" ], - "time": "2017-11-27T05:48:46+00:00" + "time": "2017-11-27 05:48:46" }, { "name": "phpunit/phpunit", @@ -5170,7 +5171,7 @@ "testing", "xunit" ], - "time": "2017-08-03T13:59:28+00:00" + "time": "2017-08-03 13:59:28" }, { "name": "phpunit/phpunit-mock-objects", @@ -5229,7 +5230,7 @@ "mock", "xunit" ], - "time": "2017-08-03T14:08:16+00:00" + "time": "2017-08-03 14:08:16" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -5274,7 +5275,7 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" + "time": "2017-03-04 06:30:41" }, { "name": "sebastian/comparator", @@ -5338,7 +5339,7 @@ "compare", "equality" ], - "time": "2017-03-03T06:26:08+00:00" + "time": "2017-03-03 06:26:08" }, { "name": "sebastian/diff", @@ -5390,7 +5391,7 @@ "keywords": [ "diff" ], - "time": "2017-05-22T07:24:03+00:00" + "time": "2017-05-22 07:24:03" }, { "name": "sebastian/environment", @@ -5440,7 +5441,7 @@ "environment", "hhvm" ], - "time": "2017-07-01T08:51:00+00:00" + "time": "2017-07-01 08:51:00" }, { "name": "sebastian/exporter", @@ -5507,7 +5508,7 @@ "export", "exporter" ], - "time": "2017-04-03T13:19:02+00:00" + "time": "2017-04-03 13:19:02" }, { "name": "sebastian/finder-facade", @@ -5546,7 +5547,7 @@ ], "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", "homepage": "https://github.com/sebastianbergmann/finder-facade", - "time": "2017-11-18T17:31:49+00:00" + "time": "2017-11-18 17:31:49" }, { "name": "sebastian/global-state", @@ -5597,7 +5598,7 @@ "keywords": [ "global state" ], - "time": "2017-04-27T15:39:26+00:00" + "time": "2017-04-27 15:39:26" }, { "name": "sebastian/object-enumerator", @@ -5644,7 +5645,7 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" + "time": "2017-08-03 12:35:26" }, { "name": "sebastian/object-reflector", @@ -5689,7 +5690,7 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" + "time": "2017-03-29 09:07:27" }, { "name": "sebastian/phpcpd", @@ -5740,7 +5741,7 @@ ], "description": "Copy/Paste Detector (CPD) for PHP code.", "homepage": "https://github.com/sebastianbergmann/phpcpd", - "time": "2016-04-17T19:32:49+00:00" + "time": "2016-04-17 19:32:49" }, { "name": "sebastian/recursion-context", @@ -5793,7 +5794,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" + "time": "2017-03-03 06:23:57" }, { "name": "sebastian/resource-operations", @@ -5835,7 +5836,7 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" + "time": "2015-07-28 20:34:47" }, { "name": "sebastian/version", @@ -5878,7 +5879,7 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" + "time": "2016-10-03 07:35:21" }, { "name": "squizlabs/php_codesniffer", @@ -5929,7 +5930,7 @@ "phpcs", "standards" ], - "time": "2017-06-14T01:23:49+00:00" + "time": "2017-06-14 01:23:49" }, { "name": "symfony/config", @@ -5991,7 +5992,7 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2018-01-21T19:05:02+00:00" + "time": "2018-01-21 19:05:02" }, { "name": "symfony/dependency-injection", @@ -6062,7 +6063,7 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2018-01-29T09:16:57+00:00" + "time": "2018-01-29 09:16:57" }, { "name": "symfony/polyfill-php54", @@ -6120,7 +6121,7 @@ "portable", "shim" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-01-30 19:27:44" }, { "name": "symfony/polyfill-php55", @@ -6176,7 +6177,7 @@ "portable", "shim" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-01-30 19:27:44" }, { "name": "symfony/polyfill-php70", @@ -6235,7 +6236,7 @@ "portable", "shim" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-01-30 19:27:44" }, { "name": "symfony/polyfill-php72", @@ -6290,7 +6291,7 @@ "portable", "shim" ], - "time": "2018-01-31T17:43:24+00:00" + "time": "2018-01-31 17:43:24" }, { "name": "symfony/polyfill-xml", @@ -6338,7 +6339,7 @@ "portable", "shim" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-01-30 19:27:44" }, { "name": "symfony/stopwatch", @@ -6387,7 +6388,7 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" + "time": "2018-01-03 07:37:34" }, { "name": "theseer/fdomdocument", @@ -6427,7 +6428,7 @@ ], "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", "homepage": "https://github.com/theseer/fDOMDocument", - "time": "2017-06-30T11:53:12+00:00" + "time": "2017-06-30 11:53:12" }, { "name": "theseer/tokenizer", @@ -6467,7 +6468,7 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2017-04-07T12:08:54+00:00" + "time": "2017-04-07 12:08:54" }, { "name": "webmozart/assert", @@ -6517,7 +6518,7 @@ "check", "validate" ], - "time": "2018-01-29T19:49:41+00:00" + "time": "2018-01-29 19:49:41" } ], "aliases": [], From c592ad543f0924f6ed0cb2cce8738d517b34cd48 Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" <a.vasiliev@sam-solutions.biz> Date: Thu, 22 Mar 2018 01:13:00 +0200 Subject: [PATCH 148/668] fix phpcs errors, unitTests, new webapi points to short and detailed bulk api statuses --- .../Api/BulkRepositoryInterface.php | 15 +- .../Api/Data/BulkStatus/DetailedInterface.php | 59 ++++++++ .../Api/Data/BulkStatus/ShortInterface.php | 59 ++++++++ .../Api/Data/OperationDetailsInterface.php | 2 +- .../DetailedInterface.php} | 26 ++-- .../Data/OperationStatus/ShortInterface.php | 54 +++++++ .../Api/Data/ShortOperationListInterface.php | 23 --- .../Model/BulkStatus.php | 141 ++++++++++-------- .../Model/BulkStatus/Detailed.php | 46 ++++++ .../Model/BulkStatus/Short.php | 46 ++++++ .../Model/Operation/Details.php | 6 +- .../Status/Detailed.php} | 15 +- .../Model/Operation/Status/Short.php | 50 +++++++ .../Collection/Synchronized/Plugin.php | 2 +- .../Model/ShortOperationList.php | 34 ----- .../Test/Unit/Model/BulkStatusTest.php | 34 ++++- .../Test/Unit/Model/Operation/DetailsTest.php | 4 + .../Test/Unit/Model/StatusMapperTest.php | 3 +- .../Magento/AsynchronousOperations/etc/di.xml | 8 +- .../etc/extension_attributes.xml | 15 -- .../AsynchronousOperations/etc/webapi.xml | 11 +- 21 files changed, 481 insertions(+), 172 deletions(-) create mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/DetailedInterface.php create mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/ShortInterface.php rename app/code/Magento/AsynchronousOperations/Api/Data/{OperationShortDetailsInterface.php => OperationStatus/DetailedInterface.php} (80%) create mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/OperationStatus/ShortInterface.php delete mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/ShortOperationListInterface.php create mode 100644 app/code/Magento/AsynchronousOperations/Model/BulkStatus/Detailed.php create mode 100644 app/code/Magento/AsynchronousOperations/Model/BulkStatus/Short.php rename app/code/Magento/AsynchronousOperations/Model/{OperationShortDetails.php => Operation/Status/Detailed.php} (83%) create mode 100644 app/code/Magento/AsynchronousOperations/Model/Operation/Status/Short.php delete mode 100644 app/code/Magento/AsynchronousOperations/Model/ShortOperationList.php delete mode 100644 app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml diff --git a/app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php b/app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php index 47a7555287b9b..5bfd07041e207 100644 --- a/app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -11,14 +10,22 @@ * @api * @since 100.3.0 */ -interface BulkRepositoryInterface extends \Magento\Framework\Bulk\BulkStatusInterface +interface BulkRepositoryInterface { /** * @param string $bulkUuid - * @return \Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface + * @return \Magento\AsynchronousOperations\Api\Data\BulkStatus\DetailedInterface * @throws \Magento\Framework\Exception\NoSuchEntityException * @since 100.3.0 */ - public function getBulkDetails($bulkUuid); + public function getBulkDetailedStatus($bulkUuid); + + /** + * @param string $bulkUuid + * @return \Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterface + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @since 100.3.0 + */ + public function getBulkShortStatus($bulkUuid); } diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/DetailedInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/DetailedInterface.php new file mode 100644 index 0000000000000..9b8d38eb368b0 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/DetailedInterface.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Api\Data\BulkStatus; + +use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface; +use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface; +use Magento\AsynchronousOperations\Api\Data\OperationStatus\DetailedListInterface; + +/** + * Interface BulkStatusInterface + * + * @api + * @since 100.3.0 + */ +interface DetailedInterface extends BulkSummaryInterface +{ + + const OPERATIONS_LIST = 'operations_list'; + const OPERATIONS_COUNTER = 'operations_counter'; + + /** + * Retrieve operations list. + * + * @return \Magento\AsynchronousOperations\Api\Data\OperationStatus\DetailedInterface[] + * @since 100.3.0 + */ + public function getOperationsList(); + + /** + * Set operations list. + * + * @param \Magento\AsynchronousOperations\Api\Data\OperationStatus\DetailedInterface[] $operationStatusList + * @return $this + * @since 100.3.0 + */ + public function setOperationsList($operationStatusList); + + /** + * Retrieve operations counter object. + * + * @return \Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface|null + * @since 100.3.0 + */ + public function getOperationsCounter(); + + /** + * Set operations counter object. + * + * @param \Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface $operationDetails + * @return $this + * @since 100.3.0 + */ + public function setOperationsCounter(OperationDetailsInterface $operationDetails + ); +} diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/ShortInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/ShortInterface.php new file mode 100644 index 0000000000000..5df4fdaa5775b --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/ShortInterface.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Api\Data\BulkStatus; + +use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface; +use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface; +use Magento\AsynchronousOperations\Api\Data\OperationStatus\ShortListInterface; + +/** + * Interface BulkStatusInterface + * + * @api + * @since 100.3.0 + */ +interface ShortInterface extends BulkSummaryInterface +{ + + const OPERATIONS_LIST = 'operations_list'; + const OPERATIONS_COUNTER = 'operations_counter'; + + /** + * Retrieve operations list. + * + * @return \Magento\AsynchronousOperations\Api\Data\OperationStatus\ShortInterface[] + * @since 100.3.0 + */ + public function getOperationsList(); + + /** + * Set operations list. + * + * @param \Magento\AsynchronousOperations\Api\Data\OperationStatus\ShortInterface[] $operationStatusList + * @return $this + * @since 100.3.0 + */ + public function setOperationsList($operationStatusList); + + /** + * Retrieve operations counter object. + * + * @return \Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface|null + * @since 100.3.0 + */ + public function getOperationsCounter(); + + /** + * Set operations counter object. + * + * @param \Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface $operationDetails + * @return $this + * @since 100.3.0 + */ + public function setOperationsCounter(OperationDetailsInterface $operationDetails + ); +} diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/OperationDetailsInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/OperationDetailsInterface.php index c071c556ace47..e7a46683d1739 100644 --- a/app/code/Magento/AsynchronousOperations/Api/Data/OperationDetailsInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/Data/OperationDetailsInterface.php @@ -7,7 +7,7 @@ namespace Magento\AsynchronousOperations\Api\Data; /** - * Interface + * Provide details of operations * * @api * @since 100.3.0 diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/OperationShortDetailsInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/OperationStatus/DetailedInterface.php similarity index 80% rename from app/code/Magento/AsynchronousOperations/Api/Data/OperationShortDetailsInterface.php rename to app/code/Magento/AsynchronousOperations/Api/Data/OperationStatus/DetailedInterface.php index 84e96bb4905e9..d72760db4f71f 100644 --- a/app/code/Magento/AsynchronousOperations/Api/Data/OperationShortDetailsInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/Data/OperationStatus/DetailedInterface.php @@ -4,19 +4,19 @@ * See COPYING.txt for license details. */ -namespace Magento\AsynchronousOperations\Api\Data; +namespace Magento\AsynchronousOperations\Api\Data\OperationStatus; -use \Magento\Framework\Bulk\OperationInterface; /** - * Getter Class OperationShortDetailsInterface + * Getter Class OperationsStatusInterface * Instead of OperationInterface this class don't provide all operation data - * and not responsive to set any data, just get operation data without serialized_data + * and not responsive to set any data, just to get operation data + * without serialized_data and result_serialized_data * * @api * @since 100.3.0 * @see \Magento\AsynchronousOperations\Api\Data\OperationInterface */ -interface OperationShortDetailsInterface +interface DetailedInterface { /** * Operation id @@ -34,14 +34,6 @@ public function getId(); */ public function getTopicName(); - /** - * Result serialized Data - * - * @return string - * @since 100.3.0 - */ - public function getResultSerializedData(); - /** * Get operation status * @@ -52,6 +44,14 @@ public function getResultSerializedData(); */ public function getStatus(); + /** + * Result serialized Data + * + * @return string + * @since 100.3.0 + */ + public function getResultSerializedData(); + /** * Get result message * diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/OperationStatus/ShortInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/OperationStatus/ShortInterface.php new file mode 100644 index 0000000000000..10d236b4bb5f8 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Api/Data/OperationStatus/ShortInterface.php @@ -0,0 +1,54 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Api\Data\OperationStatus; + +/** + * Getter Class OperationsStatusInterface + * Instead of OperationInterface this class don't provide all operation data + * and not responsive to set any data, just to get operation data + * without serialized_data and result_serialized_data + * + * @api + * @since 100.3.0 + * @see \Magento\AsynchronousOperations\Api\Data\OperationInterface + */ +interface ShortInterface +{ + /** + * Operation id + * + * @return int + * @since 100.3.0 + */ + public function getId(); + + /** + * Get operation status + * + * OPEN | COMPLETE | RETRIABLY_FAILED | NOT_RETRIABLY_FAILED + * + * @return int + * @since 100.3.0 + */ + public function getStatus(); + + /** + * Get result message + * + * @return string + * @since 100.3.0 + */ + public function getResultMessage(); + + /** + * Get error code + * + * @return int + * @since 100.3.0 + */ + public function getErrorCode(); +} diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/ShortOperationListInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/ShortOperationListInterface.php deleted file mode 100644 index a5ac69a0a9eb4..0000000000000 --- a/app/code/Magento/AsynchronousOperations/Api/Data/ShortOperationListInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\AsynchronousOperations\Api\Data; - -/** - * List of bulk operations with short operation details. - * @api - * @since 100.3.0 - */ -interface ShortOperationListInterface -{ - /** - * Get list of operations. - * - * @return \Magento\AsynchronousOperations\Api\Data\OperationShortDetailsInterface[] - * @since 100.3.0 - */ - public function getItems(); -} diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php b/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php index a0e8464641ea9..0d6978d18283c 100644 --- a/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php +++ b/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php @@ -6,6 +6,8 @@ namespace Magento\AsynchronousOperations\Model; +use Magento\AsynchronousOperations\Model\ResourceModel\Bulk\CollectionFactory as BulkCollectionFactory; +use Magento\AsynchronousOperations\Model\ResourceModel\Operation\CollectionFactory as OperationCollectionFactory; use Magento\AsynchronousOperations\Api\Data\OperationInterface; use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface; use Magento\Framework\App\ResourceConnection; @@ -14,16 +16,17 @@ use Magento\Framework\Exception\NoSuchEntityException; use Magento\Setup\Exception; use Magento\Framework\EntityManager\EntityManager; -use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterfaceFactory; -use Magento\AsynchronousOperations\Api\Data\OperationListInterfaceFactory; -use Magento\AsynchronousOperations\Api\Data\ShortOperationListInterfaceFactory; -use Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterfaceFactory; +use Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterfaceFactory as BulkStatusShortFactory; +use Magento\AsynchronousOperations\Api\Data\BulkStatus\DetailedInterfaceFactory as BulkStatusDetailedFactory; use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterfaceFactory; +use Magento\Framework\Bulk\BulkStatusInterface; +use Magento\AsynchronousOperations\Api\BulkRepositoryInterface; /** * Class BulkStatus + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class BulkStatus implements \Magento\Framework\Bulk\BulkStatusInterface +class BulkStatus implements BulkStatusInterface, BulkRepositoryInterface { /** * @var \Magento\AsynchronousOperations\Api\Data\BulkSummaryInterfaceFactory @@ -50,40 +53,25 @@ class BulkStatus implements \Magento\Framework\Bulk\BulkStatusInterface */ private $metadataPool; - /** - * @var \Magento\AsynchronousOperations\Model\ResourceModel\Bulk - */ - private $bulkResourceModel; - - /** - * @var \Magento\AsynchronousOperations\Model\BulkSummaryFactory - */ - private $bulkSummaryFactory; - /** * @var EntityManager */ private $entityManager; /** - * @var \Magento\AsynchronousOperations\Api\Data\OperationListInterfaceFactory - */ - private $operationListInterfaceFactory; - - /** - * @var \Magento\AsynchronousOperations\Api\Data\ShortOperationListInterfaceFactory + * @var \Magento\AsynchronousOperations\Api\Data\OperationDetailsInterfaceFactory */ - private $shortOperationListFactory; + private $operationCounterFactory; /** - * @var \Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterfaceFactory + * @var \Magento\AsynchronousOperations\Api\Data\BulkStatus\DetailedInterfaceFactory */ - private $bulkSummaryExtensionInterfaceFactory; + private $bulkDetailedFactory; /** - * @var \Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface + * @var \Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterfaceFactory */ - private $operationDetailsFactory; + private $bulkShortFactory; /** * Init dependencies. @@ -93,40 +81,31 @@ class BulkStatus implements \Magento\Framework\Bulk\BulkStatusInterface * @param \Magento\Framework\App\ResourceConnection $resourceConnection * @param \Magento\AsynchronousOperations\Model\BulkStatus\CalculatedStatusSql $calculatedStatusSql * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool - * @param \Magento\AsynchronousOperations\Model\ResourceModel\Bulk $bulkResourceModel - * @param \Magento\AsynchronousOperations\Api\Data\BulkSummaryInterfaceFactory $bulkSummaryFactory + * @param \Magento\AsynchronousOperations\Api\Data\BulkStatus\DetailedInterfaceFactory $bulkDetailedFactory + * @param \Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterfaceFactory $bulkShortFactory + * @param \Magento\AsynchronousOperations\Api\Data\OperationDetailsInterfaceFactory $operationCounter * @param \Magento\Framework\EntityManager\EntityManager $entityManager - * @param \Magento\AsynchronousOperations\Api\Data\OperationListInterfaceFactory $operationListInterfaceFactory - * @param \Magento\AsynchronousOperations\Api\Data\ShortOperationListInterfaceFactory $shortOperationListFactory - * @param \Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterfaceFactory $bulkSummaryExtensionInterfaceFactory - * @param \Magento\AsynchronousOperations\Api\Data\OperationDetailsInterfaceFactory $operationDetails */ public function __construct( - \Magento\AsynchronousOperations\Model\ResourceModel\Bulk\CollectionFactory $bulkCollection, - \Magento\AsynchronousOperations\Model\ResourceModel\Operation\CollectionFactory $operationCollection, + BulkCollectionFactory $bulkCollection, + OperationCollectionFactory $operationCollection, ResourceConnection $resourceConnection, CalculatedStatusSql $calculatedStatusSql, MetadataPool $metadataPool, - \Magento\AsynchronousOperations\Model\ResourceModel\Bulk $bulkResourceModel, - BulkSummaryInterfaceFactory $bulkSummaryFactory, - EntityManager $entityManager, - OperationListInterfaceFactory $operationListInterfaceFactory, - ShortOperationListInterfaceFactory $shortOperationListFactory, - BulkSummaryExtensionInterfaceFactory $bulkSummaryExtensionInterfaceFactory, - OperationDetailsInterfaceFactory $operationDetails + BulkStatusDetailedFactory $bulkDetailedFactory, + BulkStatusShortFactory $bulkShortFactory, + OperationDetailsInterfaceFactory $operationCounter, + EntityManager $entityManager ) { $this->operationCollectionFactory = $operationCollection; $this->bulkCollectionFactory = $bulkCollection; $this->resourceConnection = $resourceConnection; $this->calculatedStatusSql = $calculatedStatusSql; $this->metadataPool = $metadataPool; - $this->bulkResourceModel = $bulkResourceModel; - $this->bulkSummaryFactory = $bulkSummaryFactory; + $this->bulkDetailedFactory = $bulkDetailedFactory; + $this->bulkShortFactory = $bulkShortFactory; + $this->operationCounterFactory = $operationCounter; $this->entityManager = $entityManager; - $this->operationListInterfaceFactory = $operationListInterfaceFactory; - $this->bulkSummaryExtensionInterfaceFactory = $bulkSummaryExtensionInterfaceFactory; - $this->shortOperationListFactory = $shortOperationListFactory; - $this->operationDetailsFactory = $operationDetails; } /** @@ -179,7 +158,11 @@ public function getBulksByUser($userId) ]; $select = $collection->getSelect(); $select->columns(['status' => $this->calculatedStatusSql->get($operationTableName)]) - ->order(new \Zend_Db_Expr('FIELD(status, ' . implode(',', $statusesArray) . ')')); + ->order( + new \Zend_Db_Expr( + 'FIELD(status, ' . implode(',', $statusesArray) . ')' + ) + ); $collection->addFieldToFilter('user_id', $userId) ->addOrder('start_time'); @@ -215,13 +198,14 @@ public function getBulkStatus($bulkUuid) /** * Number of operations that has been completed successfully */ - $allCompleteOperationsQty = $this->operationCollectionFactory->create() - ->addFieldToFilter('bulk_uuid', $bulkUuid) - ->addFieldToFilter( - 'status', - OperationInterface::STATUS_TYPE_COMPLETE - ) - ->getSize(); + $allCompleteOperationsQty = $this->operationCollectionFactory + ->create() + ->addFieldToFilter('bulk_uuid', $bulkUuid) + ->addFieldToFilter( + 'status', + OperationInterface::STATUS_TYPE_COMPLETE + ) + ->getSize(); if ($allCompleteOperationsQty == $allOperationsQty) { return BulkSummaryInterface::FINISHED_SUCCESSFULLY; @@ -255,15 +239,15 @@ private function getOperationCount($bulkUuid) /** * @inheritDoc */ - public function getBulkDetails($bulkUuid) + public function getBulkDetailedStatus($bulkUuid) { - $bulkSummary = $this->bulkSummaryFactory->create(); + $bulkSummary = $this->bulkDetailedFactory->create(); - /** @var \Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface $bulk */ + /** @var \Magento\AsynchronousOperations\Api\Data\BulkStatus\DetailedInterface $bulk */ $bulk = $this->entityManager->load($bulkSummary, $bulkUuid); if ($bulk->getBulkId() === null) { - throw new \Magento\Framework\Exception\NoSuchEntityException( + throw new NoSuchEntityException( __( 'Bulk uuid %bulkUuid not exist', ['bulkUuid' => $bulkUuid] @@ -272,17 +256,42 @@ public function getBulkDetails($bulkUuid) } $operations = $this->operationCollectionFactory->create()->addFieldToFilter('bulk_uuid', $bulkUuid)->getItems(); - $operationList = $this->shortOperationListFactory->create(['items' => $operations]); /** @var \Magento\AsynchronousOperations\Model\Operation\Details $operationDetails */ - $operationDetails = $this->operationDetailsFactory->create(['bulkUuid' => $bulkUuid]); + $operationCounter = $this->operationCounterFactory->create(['bulkUuid' => $bulkUuid]); + + $bulk->setOperationsList($operations); + $bulk->setOperationsCounter($operationCounter); + + return $bulk; + } - /** @var \Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterface $bulkAttribute */ - $bulkAttribute = $this->bulkSummaryExtensionInterfaceFactory->create(); - $bulkAttribute->setOperationsList($operationList); + /** + * @inheritDoc + */ + public function getBulkShortStatus($bulkUuid) + { + $bulkSummary = $this->bulkShortFactory->create(); + + /** @var \Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterface $bulk */ + $bulk = $this->entityManager->load($bulkSummary, $bulkUuid); + + if ($bulk->getBulkId() === null) { + throw new NoSuchEntityException( + __( + 'Bulk uuid %bulkUuid not exist', + ['bulkUuid' => $bulkUuid] + ) + ); + } + + $operations = $this->operationCollectionFactory->create()->addFieldToFilter('bulk_uuid', $bulkUuid)->getItems(); + + /** @var \Magento\AsynchronousOperations\Model\Operation\Details $operationDetails */ + $operationCounter = $this->operationCounterFactory->create(['bulkUuid' => $bulkUuid]); - $bulkAttribute->setOperationsCount($operationDetails); - $bulk->setExtensionAttributes($bulkAttribute); + $bulk->setOperationsList($operations); + $bulk->setOperationsCounter($operationCounter); return $bulk; } diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkStatus/Detailed.php b/app/code/Magento/AsynchronousOperations/Model/BulkStatus/Detailed.php new file mode 100644 index 0000000000000..175ac3a1d6d0c --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Model/BulkStatus/Detailed.php @@ -0,0 +1,46 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Model\BulkStatus; + +use Magento\AsynchronousOperations\Api\Data\BulkStatus\DetailedInterface; +use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface; +use Magento\AsynchronousOperations\Model\BulkSummary; + +class Detailed extends BulkSummary implements DetailedInterface +{ + /** + * @inheritDoc + */ + public function getOperationsList() + { + return $this->getData(self::OPERATIONS_LIST); + } + + /** + * @inheritDoc + */ + public function setOperationsList($operationStatusList) + { + return $this->setData(self::OPERATIONS_LIST, $operationStatusList); + } + + /** + * @inheritDoc + */ + public function getOperationsCounter() + { + return $this->getData(self::OPERATIONS_COUNTER); + } + + /** + * @inheritDoc + */ + public function setOperationsCounter(OperationDetailsInterface $operationDetails) + { + return $this->setData(self::OPERATIONS_COUNTER, $operationDetails); + } +} diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkStatus/Short.php b/app/code/Magento/AsynchronousOperations/Model/BulkStatus/Short.php new file mode 100644 index 0000000000000..abdeed34fb578 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Model/BulkStatus/Short.php @@ -0,0 +1,46 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Model\BulkStatus; + +use Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterface; +use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface; +use Magento\AsynchronousOperations\Model\BulkSummary; + +class Short extends BulkSummary implements ShortInterface +{ + /** + * @inheritDoc + */ + public function getOperationsList() + { + return $this->getData(self::OPERATIONS_LIST); + } + + /** + * @inheritDoc + */ + public function setOperationsList($operationStatusList) + { + return $this->setData(self::OPERATIONS_LIST, $operationStatusList); + } + + /** + * @inheritDoc + */ + public function getOperationsCounter() + { + return $this->getData(self::OPERATIONS_COUNTER); + } + + /** + * @inheritDoc + */ + public function setOperationsCounter(OperationDetailsInterface $operationDetails) + { + return $this->setData(self::OPERATIONS_COUNTER, $operationDetails); + } +} diff --git a/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php b/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php index 05ea2de09f868..1dfd2cf45771d 100644 --- a/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php +++ b/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php @@ -8,6 +8,7 @@ use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface; use Magento\Framework\Bulk\OperationInterface; +use Magento\Framework\Bulk\BulkStatusInterface; class Details implements OperationDetailsInterface { @@ -40,10 +41,13 @@ class Details implements OperationDetailsInterface ]; /** + * Init dependencies. + * * @param \Magento\Framework\Bulk\BulkStatusInterface $bulkStatus + * @param null $bulkUuid */ public function __construct( - \Magento\Framework\Bulk\BulkStatusInterface $bulkStatus, + BulkStatusInterface $bulkStatus, $bulkUuid = null ) { $this->bulkStatus = $bulkStatus; diff --git a/app/code/Magento/AsynchronousOperations/Model/OperationShortDetails.php b/app/code/Magento/AsynchronousOperations/Model/Operation/Status/Detailed.php similarity index 83% rename from app/code/Magento/AsynchronousOperations/Model/OperationShortDetails.php rename to app/code/Magento/AsynchronousOperations/Model/Operation/Status/Detailed.php index 818a72bc4920b..f054c6d56fc73 100644 --- a/app/code/Magento/AsynchronousOperations/Model/OperationShortDetails.php +++ b/app/code/Magento/AsynchronousOperations/Model/Operation/Status/Detailed.php @@ -3,17 +3,18 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\AsynchronousOperations\Model; + +namespace Magento\AsynchronousOperations\Model\Operation\Status; use Magento\AsynchronousOperations\Api\Data\OperationInterface; -use Magento\AsynchronousOperations\Api\Data\OperationShortDetailsInterface; +use Magento\AsynchronousOperations\Api\Data\OperationStatus\DetailedInterface; use Magento\Framework\DataObject; use Magento\Framework\Api\ExtensibleDataInterface; /** * Class OperationShortDetails */ -class OperationShortDetails extends DataObject implements OperationShortDetailsInterface, ExtensibleDataInterface +class Detailed extends DataObject implements DetailedInterface, ExtensibleDataInterface { /** * @inheritDoc @@ -34,17 +35,17 @@ public function getTopicName() /** * @inheritDoc */ - public function getResultSerializedData() + public function getStatus() { - return $this->getData(OperationInterface::RESULT_SERIALIZED_DATA); + return $this->getData(OperationInterface::STATUS); } /** * @inheritDoc */ - public function getStatus() + public function getResultSerializedData() { - return $this->getData(OperationInterface::STATUS); + return $this->getData(OperationInterface::RESULT_SERIALIZED_DATA); } /** diff --git a/app/code/Magento/AsynchronousOperations/Model/Operation/Status/Short.php b/app/code/Magento/AsynchronousOperations/Model/Operation/Status/Short.php new file mode 100644 index 0000000000000..c799a1313a260 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Model/Operation/Status/Short.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AsynchronousOperations\Model\Operation\Status; + +use Magento\AsynchronousOperations\Api\Data\OperationInterface; +use Magento\AsynchronousOperations\Api\Data\OperationStatus\ShortInterface; +use Magento\Framework\DataObject; +use Magento\Framework\Api\ExtensibleDataInterface; + +/** + * Class OperationShortDetails + */ +class Short extends DataObject implements OperationStatusInterface, ExtensibleDataInterface +{ + /** + * @inheritDoc + */ + public function getId() + { + return $this->getData(OperationInterface::ID); + } + + /** + * @inheritDoc + */ + public function getStatus() + { + return $this->getData(OperationInterface::STATUS); + } + + /** + * @inheritDoc + */ + public function getResultMessage() + { + return $this->getData(OperationInterface::RESULT_MESSAGE); + } + + /** + * @inheritDoc + */ + public function getErrorCode() + { + return $this->getData(OperationInterface::ERROR_CODE); + } +} diff --git a/app/code/Magento/AsynchronousOperations/Model/ResourceModel/System/Message/Collection/Synchronized/Plugin.php b/app/code/Magento/AsynchronousOperations/Model/ResourceModel/System/Message/Collection/Synchronized/Plugin.php index 76c7820fa9938..8457a641ed9a9 100644 --- a/app/code/Magento/AsynchronousOperations/Model/ResourceModel/System/Message/Collection/Synchronized/Plugin.php +++ b/app/code/Magento/AsynchronousOperations/Model/ResourceModel/System/Message/Collection/Synchronized/Plugin.php @@ -143,7 +143,7 @@ private function getText($operationDetails) $summaryReport .= __( '%1 item(s) have been successfully updated.', $operationDetails['operations_successful'] - ) ; + ); } if ($operationDetails['operations_failed'] > 0) { diff --git a/app/code/Magento/AsynchronousOperations/Model/ShortOperationList.php b/app/code/Magento/AsynchronousOperations/Model/ShortOperationList.php deleted file mode 100644 index 7db033b92a068..0000000000000 --- a/app/code/Magento/AsynchronousOperations/Model/ShortOperationList.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\AsynchronousOperations\Model; - -/** - * List of bulk operations with short operation details and counter of operations. - */ -class ShortOperationList implements \Magento\AsynchronousOperations\Api\Data\ShortOperationListInterface -{ - /** - * @var array - */ - private $items; - - /** - * @param array $items [optional] - */ - public function __construct(array $items = []) - { - $this->items = $items; - } - - /** - * @inheritdoc - */ - public function getItems() - { - return $this->items; - } -} diff --git a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkStatusTest.php b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkStatusTest.php index cda55161ab852..1e2ae3ece600d 100644 --- a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkStatusTest.php +++ b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkStatusTest.php @@ -54,6 +54,21 @@ class BulkStatusTest extends \PHPUnit\Framework\TestCase */ private $metadataPoolMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $bulkDetailedFactory; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $bulkShortFactory; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $operationCounterFactory; + /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -81,6 +96,19 @@ protected function setUp() \Magento\AsynchronousOperations\Model\BulkStatus\CalculatedStatusSql::class ); $this->metadataPoolMock = $this->createMock(\Magento\Framework\EntityManager\MetadataPool::class); + $this->bulkDetailedFactory = $this->createPartialMock( + \Magento\AsynchronousOperations\Api\Data\BulkStatus\DetailedInterfaceFactory ::class, + ['create'] + ); + $this->bulkShortFactory = $this->createPartialMock( + \Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterfaceFactory::class, + ['create'] + ); + $this->operationCounterFactory = $this->createPartialMock( + \Magento\AsynchronousOperations\Api\Data\OperationDetailsInterfaceFactory::class, + ['create'] + ); + $this->entityManager = $this->createMock(\Magento\Framework\EntityManager\EntityManager::class); $this->entityMetadataMock = $this->createMock(\Magento\Framework\EntityManager\EntityMetadataInterface::class); $this->connectionMock = $this->createMock(\Magento\Framework\DB\Adapter\AdapterInterface::class); @@ -90,7 +118,11 @@ protected function setUp() $this->operationCollectionFactory, $this->resourceConnectionMock, $this->calculatedStatusSqlMock, - $this->metadataPoolMock + $this->metadataPoolMock, + $this->bulkDetailedFactory, + $this->bulkShortFactory, + $this->operationCounterFactory, + $this->entityManager ); } diff --git a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/Operation/DetailsTest.php b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/Operation/DetailsTest.php index 7060a48e77390..f62e2b7f9d5ea 100644 --- a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/Operation/DetailsTest.php +++ b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/Operation/DetailsTest.php @@ -34,6 +34,7 @@ public function testGetDetails() $failedRetriable = 23; $failedNotRetriable = 45; $open = 303; + $rejected = 0; $expectedResult = [ 'operations_total' => $completed + $failedRetriable + $failedNotRetriable + $open, @@ -41,6 +42,8 @@ public function testGetDetails() 'operations_failed' => $failedRetriable + $failedNotRetriable, 'failed_retriable' => $failedRetriable, 'failed_not_retriable' => $failedNotRetriable, + 'rejected' => $rejected, + 'open' => $open, ]; $this->bulkStatusMock->method('getOperationsCountByBulkIdAndStatus') @@ -49,6 +52,7 @@ public function testGetDetails() [$uuid, OperationInterface::STATUS_TYPE_RETRIABLY_FAILED, $failedRetriable], [$uuid, OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED, $failedNotRetriable], [$uuid, OperationInterface::STATUS_TYPE_OPEN, $open], + [$uuid, OperationInterface::STATUS_TYPE_REJECTED, $rejected], ]); $result = $this->model->getDetails($uuid); diff --git a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/StatusMapperTest.php b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/StatusMapperTest.php index 87d2bbac3cadc..89fa80de36378 100644 --- a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/StatusMapperTest.php +++ b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/StatusMapperTest.php @@ -73,7 +73,8 @@ public function testBulkSummaryStatusToOperationStatus() $this->model->bulkSummaryStatusToOperationStatus(BulkSummaryInterface::FINISHED_WITH_FAILURE), [ OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED, - OperationInterface::STATUS_TYPE_RETRIABLY_FAILED + OperationInterface::STATUS_TYPE_RETRIABLY_FAILED, + OperationInterface::STATUS_TYPE_REJECTED ] ); diff --git a/app/code/Magento/AsynchronousOperations/etc/di.xml b/app/code/Magento/AsynchronousOperations/etc/di.xml index a76f493f23e59..1f8c9291e0dd6 100644 --- a/app/code/Magento/AsynchronousOperations/etc/di.xml +++ b/app/code/Magento/AsynchronousOperations/etc/di.xml @@ -13,8 +13,10 @@ <preference for="Magento\Framework\Bulk\BulkStatusInterface" type="Magento\AsynchronousOperations\Model\BulkStatus" /> <preference for="Magento\Framework\Bulk\OperationManagementInterface" type="Magento\AsynchronousOperations\Model\OperationManagement" /> <preference for="Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface" type="Magento\AsynchronousOperations\Model\Operation\Details" /> - <preference for="Magento\AsynchronousOperations\Api\Data\OperationShortDetailsInterface" type="Magento\AsynchronousOperations\Model\OperationShortDetails" /> - <preference for="Magento\AsynchronousOperations\Api\Data\ShortOperationListInterface" type="Magento\AsynchronousOperations\Model\ShortOperationList" /> + <preference for="Magento\AsynchronousOperations\Api\Data\OperationStatus\ShortInterface" type="Magento\AsynchronousOperations\Model\Operation\Status\Short" /> + <preference for="Magento\AsynchronousOperations\Api\Data\OperationStatus\DetailedInterface" type="Magento\AsynchronousOperations\Model\Operation\Status\Detailed" /> + <preference for="Magento\AsynchronousOperations\Api\Data\BulkStatus\DetailedInterface" type="Magento\AsynchronousOperations\Model\BulkStatus\Detailed" /> + <preference for="Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterface" type="Magento\AsynchronousOperations\Model\BulkStatus\Short" /> <type name="Magento\Framework\EntityManager\MetadataPool"> <arguments> <argument name="metadata" xsi:type="array"> @@ -80,5 +82,5 @@ <virtualType name="Magento\AsynchronousOperations\Ui\Component\DataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider"/> - <preference for="Magento\AsynchronousOperations\Api\BulkRepositoryInterface" type="Magento\Framework\Bulk\BulkStatusInterface" /> + <preference for="Magento\AsynchronousOperations\Api\BulkRepositoryInterface" type="Magento\AsynchronousOperations\Model\BulkStatus" /> </config> diff --git a/app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml b/app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml deleted file mode 100644 index 7179012d440d9..0000000000000 --- a/app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd"> - <extension_attributes for="Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface"> - <attribute code="operations_list" type="Magento\AsynchronousOperations\Api\Data\ShortOperationListInterface" /> - </extension_attributes> - <extension_attributes for="Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface"> - <attribute code="operations_count" type="Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface" /> - </extension_attributes> -</config> diff --git a/app/code/Magento/AsynchronousOperations/etc/webapi.xml b/app/code/Magento/AsynchronousOperations/etc/webapi.xml index 6317387ee953d..c2b6cd8d613c5 100644 --- a/app/code/Magento/AsynchronousOperations/etc/webapi.xml +++ b/app/code/Magento/AsynchronousOperations/etc/webapi.xml @@ -8,8 +8,15 @@ <routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd"> - <route url="/V1/bulk/status/:bulkUuid" method="GET"> - <service class="Magento\AsynchronousOperations\Api\BulkRepositoryInterface" method="getBulkDetails"/> + <route url="/V1/bulk/status-detailed/:bulkUuid" method="GET"> + <service class="Magento\AsynchronousOperations\Api\BulkRepositoryInterface" method="getBulkDetailedStatus"/> + <resources> + <resource ref="Magento_Logging::system_magento_logging_bulk_operations" /> + </resources> + </route> + + <route url="/V1/bulk/status-short/:bulkUuid" method="GET"> + <service class="Magento\AsynchronousOperations\Api\BulkRepositoryInterface" method="getBulkShortStatus"/> <resources> <resource ref="Magento_Logging::system_magento_logging_bulk_operations" /> </resources> From 50eac98ae83c4631f800cbd44de70404d74a69d7 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@magento.com> Date: Thu, 22 Mar 2018 00:29:40 -0500 Subject: [PATCH 149/668] MAGETWO-89366: Create integration or api tests - integration test for GraphQlReader with user defined SDL for schema generation --- .../GraphQl/Config/GraphQlReaderTest.php | 198 + .../Framework/GraphQl/_files/schemaA.graphql | 45 + .../Framework/GraphQl/_files/schemaB.graphql | 447 ++ .../_files/schema_with_description_sdl.php | 5188 +++++++++++++++++ .../Controller/GraphQlControllerTest.php | 32 +- .../GraphQl/GraphQlIntrospectionTest.php | 2 +- 6 files changed, 5895 insertions(+), 17 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphql create mode 100644 dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaB.graphql create mode 100644 dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_with_description_sdl.php diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php new file mode 100644 index 0000000000000..8217a8ded979b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php @@ -0,0 +1,198 @@ +<?php + +namespace Magento\Framework\GraphQl\Config; + +use Magento\Framework\App\Cache; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Serialize\SerializerInterface; +use Magento\GraphQl\Controller\GraphQl; +use Magento\GraphQl\Model\SchemaGenerator; + +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** + * Tests the entire process of generating a schema from a given SDL and processing a request/query + * + * @package Magento\Framework\GraphQl\Config + * @magentoAppArea graphql + */ +class GraphQlReaderTest extends \PHPUnit\Framework\TestCase +{ + + /** @var Config */ + private $model; + + /** @var GraphQl */ + private $graphQlController; + + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var SerializerInterface */ + private $jsonSerializer; + + + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + /** @var Cache $cache */ + $cache = $this->objectManager->get(Cache::class); + $cache->clean(); + $fileResolverMock = $this->getMockBuilder( + \Magento\Framework\Config\FileResolverInterface::class + )->disableOriginalConstructor()->getMock(); + // $fileList = [file_get_contents(__DIR__ . '/../_files/schemaA.graphql')]; + $fileList = [ + file_get_contents(__DIR__ . '/../_files/schemaA.graphql'), + file_get_contents(__DIR__ . '/../_files/schemaB.graphql') + ]; + $fileResolverMock->expects($this->any())->method('get')->will($this->returnValue($fileList)); + $graphQlReader = $this->objectManager->create( + \Magento\Framework\GraphQl\Config\GraphQlReader::class, + ['fileResolver' => $fileResolverMock] + ); + $reader = $this->objectManager->create( + \Magento\Framework\GraphQl\Config\Reader::class, + ['readers' => ['graphQlReader' => $graphQlReader]] + ); + $data = $this->objectManager->create( + \Magento\Framework\GraphQl\Config\Data ::class, + ['reader' => $reader] + ); + $this->model = $this->objectManager->create( + \Magento\Framework\GraphQl\Config\Config::class, + ['data' => $data] + ); + $graphQlSchemaProvider = $this->objectManager->create( + \Magento\Framework\GraphQl\SchemaProvider::class, + ['config' =>$this->model] + ); + $typeGenerator = $this->objectManager->create( + \Magento\GraphQl\Model\Type\Generator::class, + ['schemaProvider' => $graphQlSchemaProvider] + ); + $schemaGenerator = $this->objectManager->create( + SchemaGenerator::class, + ['typeGenerator' => $typeGenerator] + ); + $this->graphQlController = $this->objectManager->create( + GraphQl::class, + ['schemaGenerator' => $schemaGenerator] + ); + $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); + } + + public function testDispatchIntrospectionWithCustomSDL() + { + $query + = <<<QUERY + query IntrospectionQuery { + __schema { + queryType { name } + types { + ...FullType + } + } +} + +fragment FullType on __Type { + kind + name + description + fields(includeDeprecated: true) { + name + description + args { + ...InputValue + } + type { + ...TypeRef + } + isDeprecated + deprecationReason + } + inputFields { + ...InputValue + } + interfaces { + ...TypeRef + } + enumValues(includeDeprecated: true) { + name + description + isDeprecated + } + possibleTypes { + ...TypeRef + } +} + +fragment InputValue on __InputValue { + name + description + type { ...TypeRef } + defaultValue +} + +fragment TypeRef on __Type { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + } + } + } + } + } + } + } +} + + +QUERY; + $postData = [ + 'query' => $query, + 'variables' => null, + 'operationName' => 'IntrospectionQuery' + ]; + /** @var Http $request */ + $request = $this->objectManager->get(\Magento\Framework\App\Request\Http::class); + $request->setPathInfo('/graphql'); + $request->setContent(json_encode($postData)); + $headers = $this->objectManager->create(\Zend\Http\Headers::class) + ->addHeaders(['Content-Type' => 'application/json']); + $request->setHeaders($headers); + $response = $this->graphQlController->dispatch($request); + $output = $this->jsonSerializer->unserialize($response->getContent()); + $expectedOutput = require __DIR__ . '/../_files/schema_with_description_sdl.php'; + $schemaResponseFields = $output['data']['__schema']['types']; + foreach ($expectedOutput as $searchTerm) { + $this->assertTrue( + (in_array($searchTerm, $schemaResponseFields)), + 'Missing type in the response' + ); + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphql b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphql new file mode 100644 index 0000000000000..395cd46aee764 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphql @@ -0,0 +1,45 @@ +type Query { + placeholder: String @doc(description: "comment for placeholder.") +} + +input FilterTypeInput @doc(description:"Comment for FilterTypeInput") { + eq: String @doc(description:"Equal") + finset: [String] + from: String + gt: String + gteq: String + in: [String] + like: String + lt: String + lteq: String + moreq: String + neq: String + notnull: String + null: String + to: String + nin: [String] +} + +type SearchResultPageInfo +@doc(description:"Comment for SearchResultPageInfo") +{ + page_size: Int @doc(description:"Comment for page_size") + current_page: Int @doc(description:"Comment for current_page") +} + +enum SortEnum @doc(description: "Comment for SortEnum.") +{ + ASC @doc(description:"Ascending Order") + DESC @doc(description:"Descending Order") +} + +interface ProductInterface { + url_key: String @doc(description: "comment for url_key inside [ProductInterface].") + url_path: String +} + + +type SimpleProduct { + url_key: String @doc(description: "comment for url_key for simple Product which implements ProductInterface") + url_path: String +} diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaB.graphql b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaB.graphql new file mode 100644 index 0000000000000..a8d317a8719dc --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaB.graphql @@ -0,0 +1,447 @@ +type Query { + products( + search: String, + filter: ProductFilterInput, + pageSize: Int, + currentPage: Int, + sort: ProductSortInput + ): Products + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") + @doc(description: "comment for products fields") +} + +enum CurrencyEnum { + AFN + GBP + EUR + INR + USD +} + +type Price { + amount: Money + adjustments: [PriceAdjustment] +} + +type PriceAdjustment { + amount: Money + code: PriceAdjustmentCodesEnum + description: PriceAdjustmentDescriptionEnum +} + +enum PriceAdjustmentCodesEnum { + TAX +} + +enum PriceAdjustmentDescriptionEnum { + INCLUDED + EXCLUDED +} + +enum PriceTypeEnum { + FIXED + PERCENT + DYNAMIC +} + +type Money { + value: Float + currency: CurrencyEnum +} + +type ProductPrices { + minimalPrice: Price + maximalPrice: Price + regularPrice: Price +} + +type ProductCategoryLinks { + position: Int + category_id: String +} + + +type ProductLinks implements ProductLinksInterface { + sku: String + link_type: String + linked_product_sku: String + linked_product_type: String + position: Int +} + +interface ProductLinksInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductLinkTypeResolverComposite") { + sku: String + link_type: String + linked_product_sku: String + linked_product_type: String + position: Int +} + +type ProductTierPrices { + customer_group_id: String + qty: Float + value: Float + percentage_value: Float + website_id: Float +} + +interface ProductInterface +@typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") +@doc(description: "comment for ProductInterface") + { + id: Int @doc(description: "comment for [ProductInterface].") + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + manufacturer: Int +} + +interface PhysicalProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") { + weight: Float +} + + +type CustomizableAreaOption implements CustomizableOptionInterface { + value: CustomizableAreaValue + product_sku: String + title: String @doc(description:"Comment for CustomizableAreaOption that implements CustomizableOptionInterface") + required: Boolean + sort_order: Int +} + +type CustomizableAreaValue { + price: Float + price_type: PriceTypeEnum + sku: String + max_characters: Int +} + +type CustomizableDateOption implements CustomizableOptionInterface { + value: CustomizableDateValue + product_sku: String + title: String + required: Boolean + sort_order: Int +} + +type CustomizableDateValue { + price: Float + price_type: PriceTypeEnum + sku: String +} + +type CustomizableDropDownOption implements CustomizableOptionInterface { + value: [CustomizableDropDownValue] + title: String + required: Boolean + sort_order: Int +} + +type CustomizableDropDownValue { + option_type_id: Int + price: Float + price_type: PriceTypeEnum + sku: String + title: String + sort_order: Int +} + +type CustomizableFieldOption implements CustomizableOptionInterface { + value: CustomizableFieldValue + product_sku: String + title: String + required: Boolean + sort_order: Int +} + +type CustomizableFieldValue { + price: Float + price_type: PriceTypeEnum + sku: String + max_characters: Int +} + +type CustomizableFileOption implements CustomizableOptionInterface { + value: CustomizableFileValue + product_sku: String + title: String + required: Boolean + sort_order: Int +} + +type CustomizableFileValue { + price: Float + price_type: PriceTypeEnum + sku: String + file_extension: String + image_size_x: Int + image_size_y: Int +} + +interface CustomizableOptionInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CustomizableOptionTypeResolver") { + title: String @doc(description:"Comment for CustomizableOptionInterface") + required: Boolean + sort_order: Int +} + +interface CustomizableProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") { + options: [CustomizableOptionInterface] +} + +type CustomizableRadioOption implements CustomizableOptionInterface { + value: [CustomizableRadioValue] + title: String + required: Boolean + sort_order: Int +} + +type CustomizableRadioValue { + option_type_id: Int + price: Float + price_type: PriceTypeEnum + sku: String + title: String + sort_order: Int +} + +type VirtualProduct implements ProductInterface, CustomizableProductInterface { + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + options: [CustomizableOptionInterface] + manufacturer: Int +} + +type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface +@doc(description: "comment for items[ProductInterface].") { + id: Int + name: String + sku: String + description: String + short_description: String + special_price: Float + special_from_date: String + special_to_date: String + attribute_set_id: Int + meta_title: String + meta_keyword: String + meta_description: String + image: String + small_image: String + thumbnail: String + new_from_date: String + new_to_date: String + tier_price: Float + custom_design: String + custom_design_from: String + custom_design_to: String + custom_layout_update: String + custom_layout: String + page_layout: String + category_ids: [Int] + options_container: String + image_label: String + small_image_label: String + thumbnail_label: String + created_at: String + updated_at: String + country_of_manufacture: String + type_id: String + website_ids: [Int] + category_links: [ProductCategoryLinks] + product_links: [ProductLinksInterface] + media_gallery_entries: [MediaGalleryEntry] + tier_prices: [ProductTierPrices] + price: ProductPrices + gift_message_available: String + weight: Float + options: [CustomizableOptionInterface] + manufacturer: Int +} + +type Products @doc(description:"Comment for Products") { + items: [ProductInterface] @doc(description: "comment for items[Products].") + page_info: SearchResultPageInfo @doc(description: "comment for page_info.") + total_count: Int +} + +input ProductFilterInput @doc(description:"Comment for ProductFilterInput") { + name: FilterTypeInput + sku: FilterTypeInput @doc(description:"Comment for field_sku which is of type FilterTypeInput") + description: FilterTypeInput + short_description: FilterTypeInput + price: FilterTypeInput + special_price: FilterTypeInput + special_from_date: FilterTypeInput + special_to_date: FilterTypeInput + weight: FilterTypeInput + manufacturer: FilterTypeInput + meta_title: FilterTypeInput + meta_keyword: FilterTypeInput + meta_description: FilterTypeInput + image: FilterTypeInput + small_image: FilterTypeInput + thumbnail: FilterTypeInput + tier_price: FilterTypeInput + news_from_date: FilterTypeInput + news_to_date: FilterTypeInput + custom_design: FilterTypeInput + custom_design_from: FilterTypeInput + custom_design_to: FilterTypeInput + custom_layout_update: FilterTypeInput + page_layout: FilterTypeInput + category_ids: FilterTypeInput + options_container: FilterTypeInput + required_options: FilterTypeInput + has_options: FilterTypeInput + image_label: FilterTypeInput + small_image_label: FilterTypeInput + thumbnail_label: FilterTypeInput + created_at: FilterTypeInput + updated_at: FilterTypeInput + country_of_manufacture: FilterTypeInput + custom_layout: FilterTypeInput + gift_message_available: FilterTypeInput + or: ProductFilterInput +} + +type ProductMediaGalleryEntriesContent @doc(description: "Comment for ProductMediaGalleryEntriesContent.") { + base64_encoded_data: String + type: String + name: String +} + +type ProductMediaGalleryEntriesVideoContent { + media_type: String + video_provider: String + video_url: String + video_title: String + video_description: String + video_metadata: String +} + +input ProductSortInput @doc(description:"Input ProductSortInput") { + name: SortEnum @doc(description:"Name") + sku: SortEnum + description: SortEnum + short_description: SortEnum + price: SortEnum + special_price: SortEnum + special_from_date: SortEnum + special_to_date: SortEnum + weight: SortEnum + manufacturer: SortEnum + meta_title: SortEnum + meta_keyword: SortEnum + meta_description: SortEnum + image: SortEnum + small_image: SortEnum + thumbnail: SortEnum + tier_price: SortEnum + news_from_date: SortEnum + news_to_date: SortEnum + custom_design: SortEnum + custom_design_from: SortEnum + custom_design_to: SortEnum + custom_layout_update: SortEnum + page_layout: SortEnum + category_ids: SortEnum + options_container: SortEnum + required_options: SortEnum + has_options: SortEnum + image_label: SortEnum + small_image_label: SortEnum + thumbnail_label: SortEnum + created_at: SortEnum + updated_at: SortEnum + country_of_manufacture: SortEnum + custom_layout: SortEnum + gift_message_available: SortEnum +} + +type MediaGalleryEntry +@doc(description: "comment for MediaGalleryEntry") +{ + id: Int @doc(description: "id for MediaGalleryEntry") + media_type: String + label: String + position: Int + disabled: Boolean + types: [String] + file: String + content: ProductMediaGalleryEntriesContent @doc(description: "Comment for ProductMediaGalleryEntriesContent on content field") + video_content: ProductMediaGalleryEntriesVideoContent +} diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_with_description_sdl.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_with_description_sdl.php new file mode 100644 index 0000000000000..8a9af4da9b9e3 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_with_description_sdl.php @@ -0,0 +1,5188 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +return [ + [ + 'kind' => 'OBJECT', + 'name' => 'Query', + 'description' => null, + 'fields' => [ + [ + 'name' => 'placeholder', + 'description' => 'comment for placeholder.', + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'products', + 'description' => 'comment for products fields', + 'args' => [ + [ + 'name' => 'search', + 'description' => '', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'filter', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'ProductFilterInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'pageSize', + 'description' => '', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'currentPage', + 'description' => '', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'sort', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'ProductSortInput', + 'ofType' => null + ], + 'defaultValue' => null + ] + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'Products', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'description' => 'The `String` scalar type represents textual data, represented as UTF-8' . "\n" . + 'character sequences. The String type is most often used by GraphQL to'. "\n" . + 'represent free-form human-readable text.', + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'ProductFilterInput', + 'description' => 'Comment for ProductFilterInput', + 'fields' => null, + 'inputFields' => [ + [ + 'name' => 'name', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'sku', + 'description' => 'Comment for field_sku which is of type FilterTypeInput', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'description', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'short_description', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'price', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'special_price', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'special_from_date', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'special_to_date', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'weight', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'manufacturer', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'meta_title', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'meta_keyword', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'meta_description', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'image', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'small_image', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'thumbnail', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'tier_price', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'news_from_date', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'news_to_date', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'custom_design', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'custom_design_from', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'custom_design_to', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'custom_layout_update', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'page_layout', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'category_ids', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'options_container', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'required_options', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'has_options', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'image_label', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'small_image_label', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'thumbnail_label', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'created_at', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'updated_at', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'country_of_manufacture', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'custom_layout', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'gift_message_available', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'or', + 'description' => '', + 'type' => [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'ProductFilterInput', + 'ofType' => null + ], + 'defaultValue' => null + ] + ], + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'FilterTypeInput', + 'description' => 'Comment for FilterTypeInput', + 'fields' => null, + 'inputFields' => [ + [ + 'name' => 'eq', + 'description' => 'Equal', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'finset', + 'description' => '', + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ] + ], + 'defaultValue' => null + ], + [ + 'name' => 'from', + 'description' => '', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'gt', + 'description' => '', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'gteq', + 'description' => '', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'in', + 'description' => '', + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ] + ], + 'defaultValue' => null + ], + [ + 'name' => 'like', + 'description' => '', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'lt', + 'description' => '', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'lteq', + 'description' => '', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'moreq', + 'description' => '', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'neq', + 'description' => '', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'notnull', + 'description' => '', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'null', + 'description' => '', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'to', + 'description' => '', + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'nin', + 'description' => '', + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ] + ], + 'defaultValue' => null + ] + ], + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'description' => 'The `Int` scalar type represents non-fractional signed whole numeric' . "\n" . + 'values. Int can represent values between -(2^31) and 2^31 - 1. ', + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'INPUT_OBJECT', + 'name' => 'ProductSortInput', + 'description' => 'Input ProductSortInput', + 'fields' => null, + 'inputFields' => [ + [ + 'name' => 'name', + 'description' => 'Name', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'sku', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'description', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'short_description', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'price', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'special_price', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'special_from_date', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'special_to_date', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'weight', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'manufacturer', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'meta_title', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'meta_keyword', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'meta_description', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'image', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'small_image', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'thumbnail', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'tier_price', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'news_from_date', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'news_to_date', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'custom_design', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'custom_design_from', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'custom_design_to', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'custom_layout_update', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'page_layout', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'category_ids', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'options_container', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'required_options', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'has_options', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'image_label', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'small_image_label', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'thumbnail_label', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'created_at', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'updated_at', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'country_of_manufacture', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'custom_layout', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ], + [ + 'name' => 'gift_message_available', + 'description' => '', + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'ofType' => null + ], + 'defaultValue' => null + ] + ], + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'ENUM', + 'name' => 'SortEnum', + 'description' => 'Comment for SortEnum.', + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => [ + [ + 'name' => 'ASC', + 'description' => 'Ascending Order', + 'isDeprecated' => false + ], + [ + 'name' => 'DESC', + 'description' => 'Descending Order', + 'isDeprecated' => false + ] + ], + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'Products', + 'description' => 'Comment for Products', + 'fields' => [ + [ + 'name' => 'items', + 'description' => 'comment for items[Products].', + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'INTERFACE', + 'name' => 'ProductInterface', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'page_info', + 'description' => 'comment for page_info.', + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'SearchResultPageInfo', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'total_count', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'INTERFACE', + 'name' => 'ProductInterface', + 'description' => 'comment for ProductInterface', + 'fields' => [ + [ + 'name' => 'url_key', + 'description' => 'comment for url_key inside [ProductInterface].', + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'url_path', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'id', + 'description' => 'comment for [ProductInterface].', + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'name', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'description', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'short_description', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'special_price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'special_from_date', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'special_to_date', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'attribute_set_id', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'meta_title', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'meta_keyword', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'meta_description', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'image', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'small_image', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'thumbnail', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'new_from_date', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'new_to_date', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'tier_price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_design', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_design_from', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_design_to', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_layout_update', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_layout', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'page_layout', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'category_ids', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'options_container', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'image_label', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'small_image_label', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'thumbnail_label', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'created_at', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'updated_at', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'country_of_manufacture', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'type_id', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'website_ids', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'category_links', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'OBJECT', + 'name' => 'ProductCategoryLinks', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'product_links', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'INTERFACE', + 'name' => 'ProductLinksInterface', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'media_gallery_entries', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'OBJECT', + 'name' => 'MediaGalleryEntry', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'tier_prices', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'OBJECT', + 'name' => 'ProductTierPrices', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'ProductPrices', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'gift_message_available', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'manufacturer', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => [ + [ + 'kind' => 'OBJECT', + 'name' => 'SimpleProduct', + 'ofType' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'VirtualProduct', + 'ofType' => null + ] + ] + ], + [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'description' => 'The `Float` scalar type represents signed double-precision fractional' . "\n" . + 'values as specified by' . "\n" . + '[IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point). ', + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'ProductCategoryLinks', + 'description' => '', + 'fields' => [ + [ + 'name' => 'position', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'category_id', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'INTERFACE', + 'name' => 'ProductLinksInterface', + 'description' => '', + 'fields' => [ + [ + 'name' => 'sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'link_type', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'linked_product_sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'linked_product_type', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'position', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => [ + [ + 'kind' => 'OBJECT', + 'name' => 'ProductLinks', + 'ofType' => null + ] + ] + ], + [ + 'kind' => 'OBJECT', + 'name' => 'MediaGalleryEntry', + 'description' => 'comment for MediaGalleryEntry', + 'fields' => [ + [ + 'name' => 'id', + 'description' => 'id for MediaGalleryEntry', + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'media_type', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'label', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'position', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'disabled', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Boolean', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'types', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'file', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'content', + 'description' => 'Comment for ProductMediaGalleryEntriesContent on content field', + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'ProductMediaGalleryEntriesContent', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'video_content', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'ProductMediaGalleryEntriesVideoContent', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'SCALAR', + 'name' => 'Boolean', + 'description' => 'The `Boolean` scalar type represents `true` or `false`.', + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'ProductMediaGalleryEntriesContent', + 'description' => 'Comment for ProductMediaGalleryEntriesContent.', + 'fields' => [ + [ + 'name' => 'base64_encoded_data', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'type', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'name', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'ProductMediaGalleryEntriesVideoContent', + 'description' => '', + 'fields' => [ + [ + 'name' => 'media_type', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'video_provider', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'video_url', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'video_title', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'video_description', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'video_metadata', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'ProductTierPrices', + 'description' => '', + 'fields' => [ + [ + 'name' => 'customer_group_id', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'qty', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'value', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'percentage_value', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'website_id', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'ProductPrices', + 'description' => '', + 'fields' => [ + [ + 'name' => 'minimalPrice', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'Price', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'maximalPrice', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'Price', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'regularPrice', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'Price', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'Price', + 'description' => '', + 'fields' => [ + [ + 'name' => 'amount', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'Money', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'adjustments', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'OBJECT', + 'name' => 'PriceAdjustment', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'Money', + 'description' => '', + 'fields' => [ + [ + 'name' => 'value', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'currency', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'CurrencyEnum', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'ENUM', + 'name' => 'CurrencyEnum', + 'description' => '', + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => [ + [ + 'name' => 'AFN', + 'description' => '', + 'isDeprecated' => false + ], + [ + 'name' => 'GBP', + 'description' => '', + 'isDeprecated' => false + ], + [ + 'name' => 'EUR', + 'description' => '', + 'isDeprecated' => false + ], + [ + 'name' => 'INR', + 'description' => '', + 'isDeprecated' => false + ], + [ + 'name' => 'USD', + 'description' => '', + 'isDeprecated' => false + ] + ], + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'PriceAdjustment', + 'description' => '', + 'fields' => [ + [ + 'name' => 'amount', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'Money', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'code', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'PriceAdjustmentCodesEnum', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'description', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'PriceAdjustmentDescriptionEnum', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'ENUM', + 'name' => 'PriceAdjustmentCodesEnum', + 'description' => '', + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => [ + [ + 'name' => 'TAX', + 'description' => '', + 'isDeprecated' => false + ] + ], + 'possibleTypes' => null + ], + [ + 'kind' => 'ENUM', + 'name' => 'PriceAdjustmentDescriptionEnum', + 'description' => '', + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => [ + [ + 'name' => 'INCLUDED', + 'description' => '', + 'isDeprecated' => false + ], + [ + 'name' => 'EXCLUDED', + 'description' => '', + 'isDeprecated' => false + ] + ], + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'SearchResultPageInfo', + 'description' => 'Comment for SearchResultPageInfo', + 'fields' => [ + [ + 'name' => 'page_size', + 'description' => 'Comment for page_size', + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'current_page', + 'description' => 'Comment for current_page', + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'SimpleProduct', + 'description' => 'comment for items[ProductInterface].', + 'fields' => [ + [ + 'name' => 'url_key', + 'description' => 'comment for url_key for simple Product which implements ProductInterface', + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'url_path', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'id', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'name', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'description', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'short_description', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'special_price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'special_from_date', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'special_to_date', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'attribute_set_id', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'meta_title', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'meta_keyword', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'meta_description', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'image', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'small_image', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'thumbnail', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'new_from_date', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'new_to_date', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'tier_price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_design', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_design_from', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_design_to', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_layout_update', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_layout', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'page_layout', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'category_ids', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'options_container', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'image_label', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'small_image_label', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'thumbnail_label', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'created_at', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'updated_at', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'country_of_manufacture', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'type_id', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'website_ids', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'category_links', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'OBJECT', + 'name' => 'ProductCategoryLinks', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'product_links', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'INTERFACE', + 'name' => 'ProductLinksInterface', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'media_gallery_entries', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'OBJECT', + 'name' => 'MediaGalleryEntry', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'tier_prices', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'OBJECT', + 'name' => 'ProductTierPrices', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'ProductPrices', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'gift_message_available', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'weight', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'options', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'INTERFACE', + 'name' => 'CustomizableOptionInterface', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'manufacturer', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + [ + 'kind' => 'INTERFACE', + 'name' => 'ProductInterface', + 'ofType' => null + ], + [ + 'kind' => 'INTERFACE', + 'name' => 'PhysicalProductInterface', + 'ofType' => null + ], + [ + 'kind' => 'INTERFACE', + 'name' => 'CustomizableProductInterface', + 'ofType' => null + ] + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'INTERFACE', + 'name' => 'PhysicalProductInterface', + 'description' => '', + 'fields' => [ + [ + 'name' => 'weight', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => [ + [ + 'kind' => 'OBJECT', + 'name' => 'SimpleProduct', + 'ofType' => null + ] + ] + ], + [ + 'kind' => 'INTERFACE', + 'name' => 'CustomizableProductInterface', + 'description' => '', + 'fields' => [ + [ + 'name' => 'options', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'INTERFACE', + 'name' => 'CustomizableOptionInterface', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => [ + [ + 'kind' => 'OBJECT', + 'name' => 'SimpleProduct', + 'ofType' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'VirtualProduct', + 'ofType' => null + ] + ] + ], + [ + 'kind' => 'INTERFACE', + 'name' => 'CustomizableOptionInterface', + 'description' => '', + 'fields' => [ + [ + 'name' => 'title', + 'description' => 'Comment for CustomizableOptionInterface', + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'required', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Boolean', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sort_order', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => [ + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableAreaOption', + 'ofType' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableDateOption', + 'ofType' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableDropDownOption', + 'ofType' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableFieldOption', + 'ofType' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableFileOption', + 'ofType' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableRadioOption', + 'ofType' => null + ] + ] + ], + [ + 'kind' => 'OBJECT', + 'name' => 'ProductLinks', + 'description' => '', + 'fields' => [ + [ + 'name' => 'sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'link_type', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'linked_product_sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'linked_product_type', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'position', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + [ + 'kind' => 'INTERFACE', + 'name' => 'ProductLinksInterface', + 'ofType' => null + ] + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableAreaOption', + 'description' => '', + 'fields' => [ + [ + 'name' => 'value', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableAreaValue', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'product_sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'title', + 'description' => 'Comment for CustomizableAreaOption that implements CustomizableOptionInterface', + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'required', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Boolean', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sort_order', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + [ + 'kind' => 'INTERFACE', + 'name' => 'CustomizableOptionInterface', + 'ofType' => null + ] + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableAreaValue', + 'description' => '', + 'fields' => [ + [ + 'name' => 'price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'price_type', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'PriceTypeEnum', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'max_characters', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'ENUM', + 'name' => 'PriceTypeEnum', + 'description' => '', + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => [ + [ + 'name' => 'FIXED', + 'description' => '', + 'isDeprecated' => false + ], + [ + 'name' => 'PERCENT', + 'description' => '', + 'isDeprecated' => false + ], + [ + 'name' => 'DYNAMIC', + 'description' => '', + 'isDeprecated' => false + ] + ], + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableDateOption', + 'description' => '', + 'fields' => [ + [ + 'name' => 'value', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableDateValue', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'product_sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'title', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'required', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Boolean', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sort_order', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + [ + 'kind' => 'INTERFACE', + 'name' => 'CustomizableOptionInterface', + 'ofType' => null + ] + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableDateValue', + 'description' => '', + 'fields' => [ + [ + 'name' => 'price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'price_type', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'PriceTypeEnum', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableDropDownOption', + 'description' => '', + 'fields' => [ + [ + 'name' => 'value', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableDropDownValue', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'title', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'required', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Boolean', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sort_order', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + [ + 'kind' => 'INTERFACE', + 'name' => 'CustomizableOptionInterface', + 'ofType' => null + ] + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableDropDownValue', + 'description' => '', + 'fields' => [ + [ + 'name' => 'option_type_id', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'price_type', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'PriceTypeEnum', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'title', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sort_order', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableFieldOption', + 'description' => '', + 'fields' => [ + [ + 'name' => 'value', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableFieldValue', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'product_sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'title', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'required', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Boolean', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sort_order', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + [ + 'kind' => 'INTERFACE', + 'name' => 'CustomizableOptionInterface', + 'ofType' => null + ] + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableFieldValue', + 'description' => '', + 'fields' => [ + [ + 'name' => 'price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'price_type', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'PriceTypeEnum', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'max_characters', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableFileOption', + 'description' => '', + 'fields' => [ + [ + 'name' => 'value', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableFileValue', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'product_sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'title', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'required', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Boolean', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sort_order', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + [ + 'kind' => 'INTERFACE', + 'name' => 'CustomizableOptionInterface', + 'ofType' => null + ] + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableFileValue', + 'description' => '', + 'fields' => [ + [ + 'name' => 'price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'price_type', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'PriceTypeEnum', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'file_extension', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'image_size_x', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'image_size_y', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableRadioOption', + 'description' => '', + 'fields' => [ + [ + 'name' => 'value', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableRadioValue', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'title', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'required', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Boolean', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sort_order', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + [ + 'kind' => 'INTERFACE', + 'name' => 'CustomizableOptionInterface', + 'ofType' => null + ] + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'CustomizableRadioValue', + 'description' => '', + 'fields' => [ + [ + 'name' => 'option_type_id', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'price_type', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'PriceTypeEnum', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'title', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sort_order', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'VirtualProduct', + 'description' => '', + 'fields' => [ + [ + 'name' => 'id', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'name', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'sku', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'description', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'short_description', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'special_price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'special_from_date', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'special_to_date', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'attribute_set_id', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'meta_title', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'meta_keyword', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'meta_description', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'image', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'small_image', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'thumbnail', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'new_from_date', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'new_to_date', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'tier_price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_design', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_design_from', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_design_to', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_layout_update', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'custom_layout', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'page_layout', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'category_ids', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'options_container', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'image_label', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'small_image_label', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'thumbnail_label', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'created_at', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'updated_at', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'country_of_manufacture', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'type_id', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'website_ids', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'category_links', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'OBJECT', + 'name' => 'ProductCategoryLinks', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'product_links', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'INTERFACE', + 'name' => 'ProductLinksInterface', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'media_gallery_entries', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'OBJECT', + 'name' => 'MediaGalleryEntry', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'tier_prices', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'OBJECT', + 'name' => 'ProductTierPrices', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'price', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'ProductPrices', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'gift_message_available', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'options', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'INTERFACE', + 'name' => 'CustomizableOptionInterface', + 'ofType' => null + ] + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'manufacturer', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + [ + 'kind' => 'INTERFACE', + 'name' => 'ProductInterface', + 'ofType' => null + ], + [ + 'kind' => 'INTERFACE', + 'name' => 'CustomizableProductInterface', + 'ofType' => null + ] + ], + 'enumValues' => null, + 'possibleTypes' => null + ] +]; diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php index 7d9e1ccbc1add..fd68bd907cc3b 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php @@ -19,7 +19,7 @@ use Magento\GraphQl\Controller\GraphQl; /** - * Class GraphQlTest + * Tests the dispatch method in the GraphQl Controller class using a simple product query * * @magentoAppArea graphql * @magentoDataFixture Magento/Catalog/_files/product_without_options.php @@ -91,8 +91,7 @@ public function testDispatch() $request->setPathInfo('/graphql'); $request->setContent(json_encode($postData)); $headers = $this->objectManager->create(\Zend\Http\Headers::class) - ->addHeaders(['Content-Type' => 'application/json'] - ); + ->addHeaders(['Content-Type' => 'application/json']); $request->setHeaders($headers); $response = $this->graphql->dispatch($request); $output = $this->jsonSerializer->unserialize($response->getContent()); @@ -134,25 +133,26 @@ public function testOutputErrorsWithMessageCategoryAndTrace() $request->setPathInfo('/graphql'); $request->setContent(json_encode($postData)); $headers = $this->objectManager->create(\Zend\Http\Headers::class) - ->addHeaders(['Content-Type' => 'application/json'] - ); + ->addHeaders(['Content-Type' => 'application/json']); $request->setHeaders($headers); $response = $this->graphql->dispatch($request); $outputResponse = $this->jsonSerializer->unserialize($response->getContent()); - if(isset($outputResponse['errors'][0])) { - if(is_array($outputResponse['errors'][0])) { - foreach($outputResponse['errors'] as $error) { - $this->assertEquals($error['category'], \Magento\Framework\GraphQl\Exception\GraphQlInputException::EXCEPTION_CATEGORY); + if (isset($outputResponse['errors'][0])) { + if (is_array($outputResponse['errors'][0])) { + foreach ($outputResponse['errors'] as $error) { + $this->assertEquals( + $error['category'], + \Magento\Framework\GraphQl\Exception\GraphQlInputException::EXCEPTION_CATEGORY + ); if (isset($error['message'])) { $this->assertEquals($error['message'], 'Invalid entity_type specified: invalid'); + } + if (isset($error['trace'])) { + if (is_array($error['trace'])) + $this->assertNotEmpty($error['trace']); + } } - if(isset($error['trace'])) - { - if(is_array($error['trace'])) - $this->assertNotEmpty($error['trace']); - } - } - } + } } } } diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/GraphQlIntrospectionTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/GraphQlIntrospectionTest.php index c605bd583f863..ed8053f561082 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQl/GraphQlIntrospectionTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQl/GraphQlIntrospectionTest.php @@ -87,7 +87,7 @@ public function testIntrospectionQuery() 'kind' => 'OBJECT', 'fields' => [ [ - 'name' => 'a', + 'name' => 'a', 'args' => [] ] ] From 93949eb457e2c11f94013c29d50f5a5213988fb1 Mon Sep 17 00:00:00 2001 From: Illia Grybkov <igrybkov@magento.com> Date: Thu, 22 Mar 2018 10:13:57 +0200 Subject: [PATCH 150/668] MAGETWO-89395: Encryption support - Remove commented code --- .../Encryption/Test/Unit/CryptTest.php | 40 +------------------ 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php b/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php index 2aacd2f2c07d0..de5a669632337 100644 --- a/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php +++ b/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php @@ -38,23 +38,7 @@ protected function _getRandomString($length) protected function _requireCipherInfo() { $filename = __DIR__ . '/Crypt/_files/_cipher_info.php'; - /* Generate allowed sizes for encryption key and init vector - $data = array(); - foreach ($this->_supportedCiphers as $cipher) { - if (!array_key_exists($cipher, $data)) { - $data[$cipher] = array(); - } - foreach ($this->_supportedModes as $mode) { - $cipherHandle = mcrypt_module_open($cipher, '', $mode, ''); - $data[$cipher][$mode] = array( - 'key_size' => mcrypt_enc_get_key_size($cipherHandle), - 'iv_size' => mcrypt_enc_get_iv_size($cipherHandle), - ); - mcrypt_module_close($cipherHandle); - } - } - file_put_contents($filename, '<?php return ' . var_export($data, true) . ";\n", LOCK_EX); - */ + if (!self::$_cipherInfo) { self::$_cipherInfo = include $filename; } @@ -138,27 +122,7 @@ public function testConstructorDefaults() public function getCryptData() { $fixturesFilename = __DIR__ . '/Crypt/_files/_crypt_fixtures.php'; - /* Generate fixtures - $fixtures = array(); - foreach (array('', 'Hello world!!!') as $inputString) { - foreach ($this->_supportedCiphers as $cipher) { - foreach ($this->_supportedModes as $mode) { - $randomKey = $this->_getRandomString($this->_getKeySize($cipher, $mode)); - $randomInitVector = $this->_getRandomString($this->_getInitVectorSize($cipher, $mode)); - $crypt = new \Magento\Framework\Encryption\Crypt($randomKey, $cipher, $mode, $randomInitVector); - $fixtures[] = array( - $randomKey, // Encryption key - $cipher, - $mode, - $randomInitVector, // Init vector - $inputString, // String to encrypt - base64_encode($crypt->encrypt($inputString)) // Store result of encryption as base64 - ); - } - } - } - file_put_contents($fixturesFilename, '<?php return ' . var_export($fixtures, true) . ";\n", LOCK_EX); - */ + $result = include $fixturesFilename; /* Restore encoded string back to binary */ foreach ($result as &$cryptParams) { From 6b8e66ae4caf34b471a7c918ba40da9b3af778f3 Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" <a.vasiliev@sam-solutions.biz> Date: Thu, 22 Mar 2018 11:34:53 +0200 Subject: [PATCH 151/668] fix undefined class, unused classes --- .../Api/Data/BulkStatus/DetailedInterface.php | 1 - .../Api/Data/BulkStatus/ShortInterface.php | 1 - app/code/Magento/AsynchronousOperations/Model/BulkStatus.php | 1 - .../Model/Entity/BulkSummaryMapper.php | 1 - .../AsynchronousOperations/Model/Operation/Status/Short.php | 2 +- .../Test/Unit/Model/BulkStatusTest.php | 5 +++++ 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/DetailedInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/DetailedInterface.php index 9b8d38eb368b0..9bbc7fc621706 100644 --- a/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/DetailedInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/DetailedInterface.php @@ -8,7 +8,6 @@ use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface; use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface; -use Magento\AsynchronousOperations\Api\Data\OperationStatus\DetailedListInterface; /** * Interface BulkStatusInterface diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/ShortInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/ShortInterface.php index 5df4fdaa5775b..cea7e7abe8c73 100644 --- a/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/ShortInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/ShortInterface.php @@ -8,7 +8,6 @@ use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface; use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface; -use Magento\AsynchronousOperations\Api\Data\OperationStatus\ShortListInterface; /** * Interface BulkStatusInterface diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php b/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php index 0d6978d18283c..d06d758352c86 100644 --- a/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php +++ b/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php @@ -14,7 +14,6 @@ use Magento\AsynchronousOperations\Model\BulkStatus\CalculatedStatusSql; use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Setup\Exception; use Magento\Framework\EntityManager\EntityManager; use Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterfaceFactory as BulkStatusShortFactory; use Magento\AsynchronousOperations\Api\Data\BulkStatus\DetailedInterfaceFactory as BulkStatusDetailedFactory; diff --git a/app/code/Magento/AsynchronousOperations/Model/Entity/BulkSummaryMapper.php b/app/code/Magento/AsynchronousOperations/Model/Entity/BulkSummaryMapper.php index 94ebbdca445c4..4abbde4c3602b 100644 --- a/app/code/Magento/AsynchronousOperations/Model/Entity/BulkSummaryMapper.php +++ b/app/code/Magento/AsynchronousOperations/Model/Entity/BulkSummaryMapper.php @@ -8,7 +8,6 @@ use Magento\Framework\EntityManager\MapperInterface; use Magento\Framework\App\ResourceConnection; use Magento\Framework\EntityManager\MetadataPool; -use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface; /** * @deprecated 100.2.0 diff --git a/app/code/Magento/AsynchronousOperations/Model/Operation/Status/Short.php b/app/code/Magento/AsynchronousOperations/Model/Operation/Status/Short.php index c799a1313a260..3d4952748dd44 100644 --- a/app/code/Magento/AsynchronousOperations/Model/Operation/Status/Short.php +++ b/app/code/Magento/AsynchronousOperations/Model/Operation/Status/Short.php @@ -14,7 +14,7 @@ /** * Class OperationShortDetails */ -class Short extends DataObject implements OperationStatusInterface, ExtensibleDataInterface +class Short extends DataObject implements ShortInterface, ExtensibleDataInterface { /** * @inheritDoc diff --git a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkStatusTest.php b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkStatusTest.php index 1e2ae3ece600d..0f1096481c936 100644 --- a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkStatusTest.php +++ b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkStatusTest.php @@ -74,6 +74,11 @@ class BulkStatusTest extends \PHPUnit\Framework\TestCase */ private $entityMetadataMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $entityManager; + /** * @var \PHPUnit_Framework_MockObject_MockObject */ From 64ddf04fc8aa9553c96345b185f44e1420f38043 Mon Sep 17 00:00:00 2001 From: Alex Lyzun <alyzun@comwrap.com> Date: Thu, 22 Mar 2018 11:26:36 +0100 Subject: [PATCH 152/668] Remove async.V1.products.POST topic cause it was there for testing --- app/code/Magento/WebapiAsync/etc/queue_consumer.xml | 4 ---- app/code/Magento/WebapiAsync/etc/queue_topology.xml | 1 - 2 files changed, 5 deletions(-) diff --git a/app/code/Magento/WebapiAsync/etc/queue_consumer.xml b/app/code/Magento/WebapiAsync/etc/queue_consumer.xml index a9cb5a5c15443..a0c123847bc47 100644 --- a/app/code/Magento/WebapiAsync/etc/queue_consumer.xml +++ b/app/code/Magento/WebapiAsync/etc/queue_consumer.xml @@ -9,8 +9,4 @@ xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/consumer.xsd"> <consumer name="async.operations.all" queue="async.operations.all" connection="amqp" consumerInstance="Magento\WebapiAsync\Model\MessageQueue\MassConsumer"/> - - <consumer name="async.V1.products.POST" queue="async.V1.products.POST" connection="amqp" - consumerInstance="Magento\WebapiAsync\Model\MessageQueue\MassConsumer" - handler="Magento\Catalog\Api\ProductRepositoryInterface::save"/> </config> \ No newline at end of file diff --git a/app/code/Magento/WebapiAsync/etc/queue_topology.xml b/app/code/Magento/WebapiAsync/etc/queue_topology.xml index 7dd9ca6e34454..9e4ac909c2261 100644 --- a/app/code/Magento/WebapiAsync/etc/queue_topology.xml +++ b/app/code/Magento/WebapiAsync/etc/queue_topology.xml @@ -8,6 +8,5 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/topology.xsd"> <exchange name="magento" type="topic" connection="amqp"> <binding id="async.operations.all" topic="async.#" destinationType="queue" destination="async.operations.all"/> - <binding id="async.V1.products.POST" topic="async.V1.products.POST" destinationType="queue" destination="async.V1.products.POST"/> </exchange> </config> From 3b276059dba0da74bfac7c90779ebc78471349c9 Mon Sep 17 00:00:00 2001 From: Renon Stewart <srenon@users.noreply.github.com> Date: Thu, 22 Mar 2018 13:35:37 +0200 Subject: [PATCH 153/668] Issues #10559 -Extend swatch using mixins For Magento 2.2 --- .../Catalog/Pricing/Render/FinalPriceBox.php | 3 +- .../Unit/Pricing/Render/FinalPriceBoxTest.php | 3 +- .../Block/Product/View/Type/Configurable.php | 43 ++++++++----- .../Product/Renderer/Listing/Configurable.php | 20 ++++++ .../templates/product/listing/renderer.phtml | 63 ++++++++++--------- 5 files changed, 84 insertions(+), 48 deletions(-) diff --git a/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php b/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php index f370c49cdfa20..e0a92ea0e0bea 100644 --- a/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php +++ b/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php @@ -115,7 +115,8 @@ protected function wrapResult($html) { return '<div class="price-box ' . $this->getData('css_classes') . '" ' . 'data-role="priceBox" ' . - 'data-product-id="' . $this->getSaleableItem()->getId() . '"' . + 'data-product-id="' . $this->getSaleableItem()->getId() . '" ' . + 'data-price-box="product-id-' . $this->getSaleableItem()->getId() . '"' . '>' . $html . '</div>'; } diff --git a/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php b/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php index e4f19e550a170..90384c122f095 100644 --- a/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php @@ -246,7 +246,8 @@ public function testRenderMsrpEnabled() //assert price wrapper $this->assertEquals( - '<div class="price-box price-final_price" data-role="priceBox" data-product-id="">test</div>', + '<div class="price-box price-final_price" data-role="priceBox" data-product-id="" ' . + 'data-price-box="product-id-">test</div>', $result ); } diff --git a/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php index 08f5bbf1383a2..b433d47b421dd 100644 --- a/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php @@ -67,7 +67,7 @@ class Configurable extends \Magento\Catalog\Block\Product\View\AbstractView /** * @var Format */ - private $localeFormat; + protected $localeFormat; /** * @var Session @@ -211,9 +211,6 @@ public function getJsonConfig() $store = $this->getCurrentStore(); $currentProduct = $this->getProduct(); - $regularPrice = $currentProduct->getPriceInfo()->getPrice('regular_price'); - $finalPrice = $currentProduct->getPriceInfo()->getPrice('final_price'); - $options = $this->helper->getOptions($currentProduct, $this->getAllowProducts()); $attributesData = $this->configurableAttributeData->getAttributesData($currentProduct, $options); @@ -223,17 +220,7 @@ public function getJsonConfig() 'currencyFormat' => $store->getCurrentCurrency()->getOutputFormat(), 'optionPrices' => $this->getOptionPrices(), 'priceFormat' => $this->localeFormat->getPriceFormat(), - 'prices' => [ - 'oldPrice' => [ - 'amount' => $this->localeFormat->getNumber($regularPrice->getAmount()->getValue()), - ], - 'basePrice' => [ - 'amount' => $this->localeFormat->getNumber($finalPrice->getAmount()->getBaseAmount()), - ], - 'finalPrice' => [ - 'amount' => $this->localeFormat->getNumber($finalPrice->getAmount()->getValue()), - ], - ], + 'prices' => $this->getPrices(), 'productId' => $currentProduct->getId(), 'chooseText' => __('Choose an Option...'), 'images' => $this->getOptionImages(), @@ -248,6 +235,32 @@ public function getJsonConfig() return $this->jsonEncoder->encode($config); } + + /** + * Get product prices for configurable variations + * + * @return array + * @since 100.2.0 + */ + protected function getPrices() + { + $currentProduct = $this->getProduct(); + + $regularPrice = $currentProduct->getPriceInfo()->getPrice('regular_price'); + $finalPrice = $currentProduct->getPriceInfo()->getPrice('final_price'); + + return [ + 'oldPrice' => [ + 'amount' => $this->localeFormat->getNumber($regularPrice->getAmount()->getValue()), + ], + 'basePrice' => [ + 'amount' => $this->localeFormat->getNumber($finalPrice->getAmount()->getBaseAmount()), + ], + 'finalPrice' => [ + 'amount' => $this->localeFormat->getNumber($finalPrice->getAmount()->getValue()), + ], + ]; + } /** * Get product images for configurable variations diff --git a/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php b/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php index 6a42ad1cc9849..54943498ee629 100644 --- a/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php +++ b/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php @@ -66,6 +66,26 @@ public function getJsonConfig() $this->unsetData('allow_products'); return parent::getJsonConfig(); } + + /** + * Composes configuration for js price format + * + * @return string + */ + public function getPriceFormatJson() + { + return $this->jsonEncoder->encode($this->localeFormat->getPriceFormat()); + } + + /** + * Composes configuration for js price + * + * @return string + */ + public function getPricesJson() + { + return $this->jsonEncoder->encode($this->getPrices()); + } /** * Do not load images for Configurable product with swatches due to its loaded by request diff --git a/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml b/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml index 7ecd6558ef6ea..e65345b38d9b2 100644 --- a/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml +++ b/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml @@ -4,37 +4,38 @@ * See COPYING.txt for license details. */ ?> -<?php /** @var $block \Magento\Swatches\Block\Product\Renderer\Configurable */ ?> -<div class="swatch-opt-<?= /* @escapeNotVerified */ $block->getProduct()->getId() ?>"></div> -<script> - require([ - 'jquery', - 'jquery/ui', - 'Magento_Swatches/js/swatch-renderer', - 'Magento_Swatches/js/catalog-add-to-cart', - 'priceBox' - ], function ($) { - var jsonConfig = <?= /* @escapeNotVerified */ $block->getJsonConfig() ?>; - - $('.swatch-opt-<?= /* @escapeNotVerified */ $block->getProduct()->getId() ?>').SwatchRenderer({ - selectorProduct: '.product-item-details', - onlySwatches: true, - enableControlLabel: false, - numberToShow: <?= /* @escapeNotVerified */ $block->getNumberSwatchesPerProduct() ?>, - jsonConfig: jsonConfig, - jsonSwatchConfig: <?= /* @escapeNotVerified */ $block->getJsonSwatchConfig() ?>, - mediaCallback: '<?= /* @escapeNotVerified */ $block->getMediaCallback() ?>' - }); - - var dataPriceBoxSelector = '[data-role=priceBox]', - dataProductIdSelector = '[data-product-id=<?= $block->escapeHtml($block->getProduct()->getId()) ?>]', - priceBoxes = $(dataPriceBoxSelector + dataProductIdSelector); +<?php +/** @var $block \Magento\Swatches\Block\Product\Renderer\Listing\Configurable */ +$productId = $block->getProduct()->getId(); +?> +<div class="swatch-opt-<?= /* @escapeNotVerified */ $productId ?>" + data-role="swatch-option-<?= /* @escapeNotVerified */ $productId ?>"></div> - priceBoxes.priceBox({ - 'priceConfig': { - priceFormat: jsonConfig.priceFormat, - prices: jsonConfig.prices +<script type="text/x-magento-init"> + { + "[data-role=swatch-option-<?= /* @escapeNotVerified */ $productId ?>]": { + "Magento_Swatches/js/swatch-renderer": { + "selectorProduct": ".product-item-details", + "onlySwatches": true, + "enableControlLabel": false, + "numberToShow": <?= /* @escapeNotVerified */ $block->getNumberSwatchesPerProduct(); ?>, + "jsonConfig": <?= /* @escapeNotVerified */ $block->getJsonConfig(); ?>, + "jsonSwatchConfig": <?= /* @escapeNotVerified */ $block->getJsonSwatchConfig(); ?>, + "mediaCallback": "<?= /* @escapeNotVerified */ $block->getMediaCallback() ?>" } - }); - }); + } + } </script> + +<script type="text/x-magento-init"> + { + "[data-role=priceBox][data-price-box=product-id-<?= /* @escapeNotVerified */ $productId ?>]": { + "priceBox": { + "priceConfig": { + "priceFormat": <?= /* @escapeNotVerified */ $block->getPriceFormatJson(); ?>, + "prices": <?= /* @escapeNotVerified */ $block->getPricesJson(); ?> + } + } + } + } +</script> \ No newline at end of file From 1df72c517584369c6ef9e2c84ab1baf5314bf686 Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@magento.com> Date: Tue, 20 Mar 2018 12:43:18 +0200 Subject: [PATCH 154/668] MAGETWO-89455: Add layered navigation information to product results --- .../CatalogGraphQl/Model/Layer/Category.php | 23 +++++ .../CatalogGraphQl/Model/Layer/Search.php | 8 ++ .../Layer/DataProvider/LayerFilters.php | 93 +++++++++++++++++++ .../Layer/FilterableAttributesListFactory.php | 52 +++++++++++ .../Model/Resolver/Products.php | 24 ++++- .../Products/DataProvider/Product.php | 10 +- .../Magento/CatalogGraphQl/etc/graphql.xml | 12 +++ .../Magento/CatalogGraphQl/etc/graphql/di.xml | 18 ++++ 8 files changed, 236 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Layer/Category.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Layer/Search.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/DataProvider/LayerFilters.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/FilterableAttributesListFactory.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Layer/Category.php b/app/code/Magento/CatalogGraphQl/Model/Layer/Category.php new file mode 100644 index 0000000000000..bb40d8aff4bb1 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Layer/Category.php @@ -0,0 +1,23 @@ +<?php + +namespace Magento\CatalogGraphQl\Model\Layer; + +class Category extends \Magento\Catalog\Model\Layer +{ + const LAYER_GRAPHQL_CATEGORY = 'graphql_category'; + + /** + * @var \Magento\Catalog\Model\ResourceModel\Product\Collection + */ + protected $_productCollections; + + public function setCollection(\Magento\Catalog\Model\ResourceModel\Product\Collection $collection) + { + $this->_productCollections[$this->getCurrentCategory()->getId()] = $collection; + } + + public function getProductCollection() + { + return $this->_productCollections[$this->getCurrentCategory()->getId()]; + } +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/Model/Layer/Search.php b/app/code/Magento/CatalogGraphQl/Model/Layer/Search.php new file mode 100644 index 0000000000000..184586127ac10 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Layer/Search.php @@ -0,0 +1,8 @@ +<?php + +namespace Magento\CatalogGraphQl\Model\Layer; + +class Search extends Category +{ + const LAYER_GRAPHQL_SEARCH = 'graphql_search'; +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/DataProvider/LayerFilters.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/DataProvider/LayerFilters.php new file mode 100644 index 0000000000000..b0cb85d63ab30 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/DataProvider/LayerFilters.php @@ -0,0 +1,93 @@ +<?php + +namespace Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider; + +use Magento\Catalog\Model\Layer\Filter\AbstractFilter; +use Magento\Catalog\Model\Layer\FilterListFactory; +use Magento\Catalog\Model\Layer\Resolver; +use Magento\CatalogGraphQl\Model\Resolver\Layer\FilterableAttributesListFactory; +use Magento\Framework\Registry; + +class LayerFilters +{ + + /** + * @var Resolver + */ + private $layerResolver; + + /** + * @var FilterListFactory + */ + private $filterListFactory; + + /** + * @var FilterableAttributesListFactory + */ + private $filterableAttributesListFactory; + + /** + * @var Registry + */ + private $registry; + + /** + * LayerFilters constructor. + * @param Resolver $layerResolver + * @param FilterListFactory $filterListFactory + * @param FilterableAttributesListFactory $filterableAttributesListFactory + */ + public function __construct( + Resolver $layerResolver, + FilterListFactory $filterListFactory, + FilterableAttributesListFactory $filterableAttributesListFactory, + Registry $registry + ) { + $this->layerResolver = $layerResolver; + $this->filterListFactory = $filterListFactory; + $this->filterableAttributesListFactory = $filterableAttributesListFactory; + $this->registry = $registry; + } + + /** + * Get filters. + * + * @param string $type + * @return array + */ + public function getFilters($type) + { + $filterableAttributesList = $this->filterableAttributesListFactory->create( + Resolver::CATALOG_LAYER_SEARCH + ); + /** @var \Magento\Catalog\Model\Layer $layer */ + $layer = $this->layerResolver->get(); + $filterList = $this->filterListFactory->create( + [ + 'filterableAttributes' => $filterableAttributesList + ] + ); + $filters = $filterList->getFilters($layer); + $filtersArray = []; + /** @var AbstractFilter $filter */ + foreach ($filters as $filter) { + if ($filter->getItemsCount()) { + $filterGroup = [ + 'name' => (string)$filter->getName(), + 'filter_items_count' => $filter->getItemsCount(), + 'request_var' => $filter->getRequestVar(), + ]; + /** @var \Magento\Catalog\Model\Layer\Filter\Item $filterItem */ + foreach ($filter->getItems() as $filterItem) { + $filterGroup['filter_items'][] = [ + 'label' => (string)$filterItem->getLabel(), + 'value_string' => $filterItem->getValueString(), + 'items_count' => $filterItem->getCount(), + ]; + } + $filtersArray[] = $filterGroup; + } + } + return $filtersArray; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/FilterableAttributesListFactory.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/FilterableAttributesListFactory.php new file mode 100644 index 0000000000000..18f2b444edb4c --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/FilterableAttributesListFactory.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogGraphQl\Model\Resolver\Layer; + +use Magento\Catalog\Model\Layer\Category\FilterableAttributeList as CategoryFilterableAttributeList; +use Magento\Catalog\Model\Layer\Resolver; +use Magento\Catalog\Model\Layer\Search\FilterableAttributeList; + +/** + * Class FilterableAttributesListFactory + * @package Magento\CatalogGraphQl\Model\Resolver\Layer + */ +class FilterableAttributesListFactory +{ + /** + * Object Manager instance + * + * @var \Magento\Framework\ObjectManagerInterface + */ + protected $_objectManager = null; + + /** + * Factory constructor + * + * @param \Magento\Framework\ObjectManagerInterface $objectManager + */ + public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager) + { + $this->_objectManager = $objectManager; + } + + /** + * Create class instance with specified parameters + * + * @param $type + * @param array $data + * @return \Magento\Catalog\Model\Layer\FilterList + */ + public function create($type, array $data = array()) + { + if ($type === Resolver::CATALOG_LAYER_CATEGORY) { + return $this->_objectManager->create(CategoryFilterableAttributeList::class, $data); + } elseif ($type === Resolver::CATALOG_LAYER_SEARCH) { + return $this->_objectManager->create(FilterableAttributeList::class, $data); + } + throw new \InvalidArgumentException('Unknown filterable attribtues list type: ' . $type); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php index bf832ba5830dc..7255501c52920 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php @@ -42,6 +42,15 @@ class Products implements ResolverInterface */ private $valueFactory; + /** + * @var Layer\DataProvider\LayerFilters + */ + private $layerFiltersDataProvider; + /** + * @var \Magento\Catalog\Model\Layer\Resolver + */ + private $layerResolver; + /** * @param Builder $searchCriteriaBuilder * @param Search $searchQuery @@ -52,11 +61,15 @@ public function __construct( Builder $searchCriteriaBuilder, Search $searchQuery, Filter $filterQuery, + \Magento\Catalog\Model\Layer\Resolver $layerResolver, + \Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\LayerFilters $layerFiltersDataProvider, ValueFactory $valueFactory ) { $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->searchQuery = $searchQuery; $this->filterQuery = $filterQuery; + $this->layerFiltersDataProvider = $layerFiltersDataProvider; + $this->layerResolver = $layerResolver; $this->valueFactory = $valueFactory; } @@ -71,17 +84,21 @@ public function resolve( ResolveInfo $info ) : ?Value { $searchCriteria = $this->searchCriteriaBuilder->build($args); - if (!isset($args['search']) && !isset($args['filter'])) { throw new GraphQlInputException( __("'search' or 'filter' input argument is required.") ); } elseif (isset($args['search'])) { + $this->layerResolver->create(\Magento\CatalogGraphQl\Model\Layer\Search::LAYER_GRAPHQL_SEARCH); $searchResult = $this->searchQuery->getResult($searchCriteria); + $this->layerResolver->get(); + $layerFilters = $this->layerFiltersDataProvider->getFilters(\Magento\CatalogGraphQl\Model\Layer\Search::LAYER_GRAPHQL_SEARCH); } else { + $this->layerResolver->create(\Magento\CatalogGraphQl\Model\Layer\Category::LAYER_GRAPHQL_CATEGORY); + $this->layerResolver->get(); $searchResult = $this->filterQuery->getResult($searchCriteria); + $layerFilters = $this->layerFiltersDataProvider->getFilters(\Magento\CatalogGraphQl\Model\Layer\Category::LAYER_GRAPHQL_CATEGORY); } - //possible division by 0 if ($searchCriteria->getPageSize()) { $maxPages = ceil($searchResult->getTotalCount() / $searchCriteria->getPageSize()); @@ -105,7 +122,8 @@ public function resolve( 'page_info' => [ 'page_size' => $searchCriteria->getPageSize(), 'current_page' => $currentPage - ] + ], + 'filters' => $layerFilters, ]; $result = function () use ($data) { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php index 6d508b9ec1413..4bc3377c11541 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php @@ -39,6 +39,11 @@ class Product */ private $searchResultsFactory; + /** + * @var \Magento\Catalog\Model\Layer\Resolver + */ + private $layerResolver; + /** * @param CollectionFactory $collectionFactory * @param JoinProcessorInterface $joinProcessor @@ -49,12 +54,14 @@ public function __construct( CollectionFactory $collectionFactory, JoinProcessorInterface $joinProcessor, CollectionProcessorInterface $collectionProcessor, - ProductSearchResultsInterfaceFactory $searchResultsFactory + ProductSearchResultsInterfaceFactory $searchResultsFactory, + \Magento\Catalog\Model\Layer\Resolver $layerResolver ) { $this->collectionFactory = $collectionFactory; $this->joinProcessor = $joinProcessor; $this->collectionProcessor = $collectionProcessor; $this->searchResultsFactory = $searchResultsFactory; + $this->layerResolver = $layerResolver; } /** @@ -67,6 +74,7 @@ public function getList(SearchCriteriaInterface $searchCriteria) : SearchResults { /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */ $collection = $this->collectionFactory->create(); + $this->layerResolver->get()->setCollection($collection); $this->joinProcessor->process($collection); $collection->addAttributeToSelect('*'); diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql.xml b/app/code/Magento/CatalogGraphQl/etc/graphql.xml index d6fe68a540890..61d39554ef980 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql.xml @@ -371,8 +371,20 @@ <field xsi:type="ObjectInputField" name="custom_layout" type="SortEnum" description="The name of a custom layout."/> <field xsi:type="ObjectInputField" name="gift_message_available" type="SortEnum" description="Indicates whether a gift message is available."/> </type> + <type xsi:type="OutputType" name="LayerFilter"> + <field xsi:type="ScalarOutputField" name="name" type="String" description="Filter name"/> + <field xsi:type="ScalarOutputField" name="request_var" type="String" description="Variable to be passed to request"/> + <field xsi:type="ScalarOutputField" name="filter_items_count" type="Int" description="Count of items matching filter."/> + <field xsi:type="ObjectArrayOutputField" name="filter_items" itemType="LayerFilterItem" description="Attribute code for attribtue based filter"/> + </type> + <type xsi:type="OutputType" name="LayerFilterItem"> + <field xsi:type="ScalarOutputField" name="label" type="String" description="Filter item label"/> + <field xsi:type="ScalarOutputField" name="value_string" type="String" description="Filter value"/> + <field xsi:type="ScalarOutputField" name="items_count" type="Int" description="Filter result items count"/> + </type> <type xsi:type="OutputType" name="Products"> <field xsi:type="ObjectArrayOutputField" name="items" itemType="ProductInterface" description="An array of products that match the specified search criteria.."/> + <field xsi:type="ObjectArrayOutputField" name="filters" itemType="LayerFilter" description="An array of Layer filters."/> <field xsi:type="ObjectOutputField" name="page_info" type="SearchResultPageInfo" description="An object that includes the `page_info` and `currentPage` values specified in the query"/> <field xsi:type="ScalarOutputField" name="total_count" type="Int" description="The number of products returned."/> </type> diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index 32717bfc151c4..4ee27a953a628 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -54,4 +54,22 @@ </argument> </arguments> </type> + <type name="Magento\Catalog\Model\Layer\Resolver"> + <arguments> + <argument name="layersPool" xsi:type="array"> + <item name="graphql_category" xsi:type="string">Magento\CatalogGraphQl\Model\Layer\Category</item> + <item name="graphql_search" xsi:type="string">Magento\CatalogGraphQl\Model\Layer\Search</item> + </argument> + </arguments> + </type> + <type name="Magento\CatalogGraphQl\Model\Layer\Search"> + <arguments> + <argument name="context" xsi:type="object">Magento\Catalog\Model\Layer\Search\Context</argument> + </arguments> + </type> + <type name="Magento\CatalogGraphQl\Model\Layer\Category"> + <arguments> + <argument name="context" xsi:type="object">Magento\Catalog\Model\Layer\Category\Context</argument> + </arguments> + </type> </config> From 3ad89312c7f9485cbdf746675f69638997c05446 Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@magento.com> Date: Thu, 22 Mar 2018 14:29:22 +0200 Subject: [PATCH 155/668] MAGETWO-89455: Add layered navigation information to product results --- .../Model/Layer/CollectionProvider.php | 44 +++++++++ .../CatalogGraphQl/Model/Layer/Context.php | 71 ++++++++++++++ .../Layer/DataProvider/LayerFilters.php | 93 ------------------- .../Layer/FilterableAttributesListFactory.php | 1 - .../Model/Resolver/Products.php | 67 ++++++++++--- .../Products/DataProvider/Product.php | 3 +- .../Model/Resolver/Products/Query/Filter.php | 15 ++- app/code/Magento/CatalogGraphQl/etc/di.xml | 1 + .../Magento/CatalogGraphQl/etc/graphql/di.xml | 18 ++-- .../Magento/CatalogSearchGraphQl/LICENSE.txt | 48 ++++++++++ .../CatalogSearchGraphQl/LICENSE_AFL.txt | 48 ++++++++++ .../Magento/CatalogSearchGraphQl/README.md | 0 .../CatalogSearchGraphQl/composer.json | 28 ++++++ .../CatalogSearchGraphQl/etc/graphql/di.xml | 29 ++++++ .../CatalogSearchGraphQl/etc/module.xml | 16 ++++ .../CatalogSearchGraphQl/registration.php | 9 ++ 16 files changed, 365 insertions(+), 126 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Layer/CollectionProvider.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Layer/Context.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/DataProvider/LayerFilters.php create mode 100644 app/code/Magento/CatalogSearchGraphQl/LICENSE.txt create mode 100644 app/code/Magento/CatalogSearchGraphQl/LICENSE_AFL.txt create mode 100644 app/code/Magento/CatalogSearchGraphQl/README.md create mode 100644 app/code/Magento/CatalogSearchGraphQl/composer.json create mode 100644 app/code/Magento/CatalogSearchGraphQl/etc/graphql/di.xml create mode 100644 app/code/Magento/CatalogSearchGraphQl/etc/module.xml create mode 100644 app/code/Magento/CatalogSearchGraphQl/registration.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Layer/CollectionProvider.php b/app/code/Magento/CatalogGraphQl/Model/Layer/CollectionProvider.php new file mode 100644 index 0000000000000..c93a4e86c21c1 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Layer/CollectionProvider.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogGraphQl\Model\Layer; + +use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; +use Magento\Catalog\Model\ResourceModel\Product\Collection; + +/** + * Class CollectionProvider + * @package Magento\CatalogGraphQl\Model\Layer + */ +class CollectionProvider implements \Magento\Catalog\Model\Layer\ItemCollectionProviderInterface +{ + /** + * @var CollectionFactory + */ + private $collectionFactory; + + /** + * @var Collection + */ + private $collection; + + public function __construct( + CollectionFactory $collectionFactory + ) { + $this->collectionFactory = $collectionFactory; + } + + /** + * @param \Magento\Catalog\Model\Category $category + * @return \Magento\Catalog\Model\ResourceModel\Product\Collection + */ + public function getCollection(\Magento\Catalog\Model\Category $category) + { + if (!$this->collection) { + $this->collection = $this->collectionFactory->create(); + } + return $this->collection; + } +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/Model/Layer/Context.php b/app/code/Magento/CatalogGraphQl/Model/Layer/Context.php new file mode 100644 index 0000000000000..ef1996111c65c --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Layer/Context.php @@ -0,0 +1,71 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogGraphQl\Model\Layer; + +use Magento\Catalog\Model\Layer\CollectionFilterInterface; +use Magento\Catalog\Model\Layer\ItemCollectionProviderInterface; +use Magento\Catalog\Model\Layer\StateKeyInterface; + +/** + * Class Context + * @package Magento\CatalogGraphQl\Model\Layer + */ +class Context implements \Magento\Catalog\Model\Layer\ContextInterface +{ + /** + * @var ItemCollectionProviderInterface + */ + protected $collectionProvider; + + /** + * @var StateKeyInterface + */ + protected $stateKey; + + /** + * @var CollectionFilterInterface + */ + protected $collectionFilter; + + /** + * @param ItemCollectionProviderInterface $collectionProvider + * @param StateKeyInterface $stateKey + * @param CollectionFilterInterface $collectionFilter + */ + public function __construct( + ItemCollectionProviderInterface $collectionProvider, + StateKeyInterface $stateKey, + CollectionFilterInterface $collectionFilter + ) { + $this->collectionProvider = $collectionProvider; + $this->stateKey = $stateKey; + $this->collectionFilter = $collectionFilter; + } + + /** + * @return ItemCollectionProviderInterface + */ + public function getCollectionProvider() + { + return $this->collectionProvider; + } + + /** + * @return StateKeyInterface + */ + public function getStateKey() + { + return $this->stateKey; + } + + /** + * @return CollectionFilterInterface + */ + public function getCollectionFilter() + { + return $this->collectionFilter; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/DataProvider/LayerFilters.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/DataProvider/LayerFilters.php deleted file mode 100644 index b0cb85d63ab30..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/DataProvider/LayerFilters.php +++ /dev/null @@ -1,93 +0,0 @@ -<?php - -namespace Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider; - -use Magento\Catalog\Model\Layer\Filter\AbstractFilter; -use Magento\Catalog\Model\Layer\FilterListFactory; -use Magento\Catalog\Model\Layer\Resolver; -use Magento\CatalogGraphQl\Model\Resolver\Layer\FilterableAttributesListFactory; -use Magento\Framework\Registry; - -class LayerFilters -{ - - /** - * @var Resolver - */ - private $layerResolver; - - /** - * @var FilterListFactory - */ - private $filterListFactory; - - /** - * @var FilterableAttributesListFactory - */ - private $filterableAttributesListFactory; - - /** - * @var Registry - */ - private $registry; - - /** - * LayerFilters constructor. - * @param Resolver $layerResolver - * @param FilterListFactory $filterListFactory - * @param FilterableAttributesListFactory $filterableAttributesListFactory - */ - public function __construct( - Resolver $layerResolver, - FilterListFactory $filterListFactory, - FilterableAttributesListFactory $filterableAttributesListFactory, - Registry $registry - ) { - $this->layerResolver = $layerResolver; - $this->filterListFactory = $filterListFactory; - $this->filterableAttributesListFactory = $filterableAttributesListFactory; - $this->registry = $registry; - } - - /** - * Get filters. - * - * @param string $type - * @return array - */ - public function getFilters($type) - { - $filterableAttributesList = $this->filterableAttributesListFactory->create( - Resolver::CATALOG_LAYER_SEARCH - ); - /** @var \Magento\Catalog\Model\Layer $layer */ - $layer = $this->layerResolver->get(); - $filterList = $this->filterListFactory->create( - [ - 'filterableAttributes' => $filterableAttributesList - ] - ); - $filters = $filterList->getFilters($layer); - $filtersArray = []; - /** @var AbstractFilter $filter */ - foreach ($filters as $filter) { - if ($filter->getItemsCount()) { - $filterGroup = [ - 'name' => (string)$filter->getName(), - 'filter_items_count' => $filter->getItemsCount(), - 'request_var' => $filter->getRequestVar(), - ]; - /** @var \Magento\Catalog\Model\Layer\Filter\Item $filterItem */ - foreach ($filter->getItems() as $filterItem) { - $filterGroup['filter_items'][] = [ - 'label' => (string)$filterItem->getLabel(), - 'value_string' => $filterItem->getValueString(), - 'items_count' => $filterItem->getCount(), - ]; - } - $filtersArray[] = $filterGroup; - } - } - return $filtersArray; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/FilterableAttributesListFactory.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/FilterableAttributesListFactory.php index 18f2b444edb4c..dc9571794538a 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/FilterableAttributesListFactory.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Layer/FilterableAttributesListFactory.php @@ -3,7 +3,6 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\CatalogGraphQl\Model\Resolver\Layer; use Magento\Catalog\Model\Layer\Category\FilterableAttributeList as CategoryFilterableAttributeList; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php index 7255501c52920..011ea1a924d24 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php @@ -10,6 +10,8 @@ use GraphQL\Type\Definition\ResolveInfo; use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Catalog\Model\Layer\Filter\AbstractFilter; +use Magento\Catalog\Model\Layer\Resolver; use Magento\Framework\GraphQl\Argument\SearchCriteria\Builder; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Filter; @@ -43,13 +45,19 @@ class Products implements ResolverInterface private $valueFactory; /** - * @var Layer\DataProvider\LayerFilters + * @var Resolver */ - private $layerFiltersDataProvider; + private $layerResolver; + /** - * @var \Magento\Catalog\Model\Layer\Resolver + * @var \Magento\CatalogGraphQl\Model\Resolver\Layer\FilterableAttributesListFactory */ - private $layerResolver; + private $filterableAttributesListFactory; + + /** + * @var \Magento\Catalog\Model\Layer\FilterListFactory + */ + private $filterListFactory; /** * @param Builder $searchCriteriaBuilder @@ -61,15 +69,17 @@ public function __construct( Builder $searchCriteriaBuilder, Search $searchQuery, Filter $filterQuery, + ValueFactory $valueFactory, \Magento\Catalog\Model\Layer\Resolver $layerResolver, - \Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\LayerFilters $layerFiltersDataProvider, - ValueFactory $valueFactory + \Magento\Catalog\Model\Layer\FilterListFactory $filterListFactory, + \Magento\CatalogGraphQl\Model\Resolver\Layer\FilterableAttributesListFactory $filterableAttributesListFactory ) { $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->searchQuery = $searchQuery; $this->filterQuery = $filterQuery; - $this->layerFiltersDataProvider = $layerFiltersDataProvider; $this->layerResolver = $layerResolver; + $this->filterableAttributesListFactory = $filterableAttributesListFactory; + $this->filterListFactory = $filterListFactory; $this->valueFactory = $valueFactory; } @@ -89,15 +99,17 @@ public function resolve( __("'search' or 'filter' input argument is required.") ); } elseif (isset($args['search'])) { - $this->layerResolver->create(\Magento\CatalogGraphQl\Model\Layer\Search::LAYER_GRAPHQL_SEARCH); + $this->layerResolver->create(Resolver::CATALOG_LAYER_SEARCH); + $filterableAttributesList = $this->filterableAttributesListFactory->create( + Resolver::CATALOG_LAYER_SEARCH + ); $searchResult = $this->searchQuery->getResult($searchCriteria); - $this->layerResolver->get(); - $layerFilters = $this->layerFiltersDataProvider->getFilters(\Magento\CatalogGraphQl\Model\Layer\Search::LAYER_GRAPHQL_SEARCH); } else { - $this->layerResolver->create(\Magento\CatalogGraphQl\Model\Layer\Category::LAYER_GRAPHQL_CATEGORY); - $this->layerResolver->get(); + $this->layerResolver->create(Resolver::CATALOG_LAYER_CATEGORY); + $filterableAttributesList = $this->filterableAttributesListFactory->create( + Resolver::CATALOG_LAYER_CATEGORY + ); $searchResult = $this->filterQuery->getResult($searchCriteria); - $layerFilters = $this->layerFiltersDataProvider->getFilters(\Magento\CatalogGraphQl\Model\Layer\Category::LAYER_GRAPHQL_CATEGORY); } //possible division by 0 if ($searchCriteria->getPageSize()) { @@ -105,7 +117,32 @@ public function resolve( } else { $maxPages = 0; } - + $filterList = $this->filterListFactory->create( + [ + 'filterableAttributes' => $filterableAttributesList + ] + ); + $filters = $filterList->getFilters($this->layerResolver->get()); + $filtersArray = []; + /** @var AbstractFilter $filter */ + foreach ($filters as $filter) { + if ($filter->getItemsCount()) { + $filterGroup = [ + 'name' => (string)$filter->getName(), + 'filter_items_count' => $filter->getItemsCount(), + 'request_var' => $filter->getRequestVar(), + ]; + /** @var \Magento\Catalog\Model\Layer\Filter\Item $filterItem */ + foreach ($filter->getItems() as $filterItem) { + $filterGroup['filter_items'][] = [ + 'label' => (string)$filterItem->getLabel(), + 'value_string' => $filterItem->getValueString(), + 'items_count' => $filterItem->getCount(), + ]; + } + $filtersArray[] = $filterGroup; + } + } $currentPage = $searchCriteria->getCurrentPage(); if ($searchCriteria->getCurrentPage() > $maxPages && $searchResult->getTotalCount() > 0) { $currentPage = new GraphQlInputException( @@ -123,7 +160,7 @@ public function resolve( 'page_size' => $searchCriteria->getPageSize(), 'current_page' => $currentPage ], - 'filters' => $layerFilters, + 'filters' => $filtersArray ]; $result = function () use ($data) { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php index 4bc3377c11541..5184732968b5f 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php @@ -73,8 +73,7 @@ public function __construct( public function getList(SearchCriteriaInterface $searchCriteria) : SearchResultsInterface { /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */ - $collection = $this->collectionFactory->create(); - $this->layerResolver->get()->setCollection($collection); + $collection = $this->layerResolver->get()->getProductCollection(); $this->joinProcessor->process($collection); $collection->addAttributeToSelect('*'); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php index 1c05346ab0fe5..00e9287b61a07 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php @@ -25,7 +25,7 @@ class Filter private $searchResultFactory; /** - * @var Product + * @var \Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product */ private $productDataProvider; @@ -39,22 +39,31 @@ class Filter */ private $postProcessors; + /** + * @var \Magento\Catalog\Model\Layer\Resolver + */ + private $layerResolver; + /** * @param SearchResultFactory $searchResultFactory - * @param Product $productDataProvider + * @param \Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product $productDataProvider * @param FormatterInterface $formatter + * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver * @param PostFetchProcessorInterface[] $postProcessors + * @internal param Product $productDataProvider */ public function __construct( SearchResultFactory $searchResultFactory, - Product $productDataProvider, + \Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product $productDataProvider, FormatterInterface $formatter, + \Magento\Catalog\Model\Layer\Resolver $layerResolver, array $postProcessors = [] ) { $this->searchResultFactory = $searchResultFactory; $this->productDataProvider = $productDataProvider; $this->postProcessors = $postProcessors; $this->formatter = $formatter; + $this->layerResolver = $layerResolver; } /** diff --git a/app/code/Magento/CatalogGraphQl/etc/di.xml b/app/code/Magento/CatalogGraphQl/etc/di.xml index b7338139e5b9f..a2252c624200d 100644 --- a/app/code/Magento/CatalogGraphQl/etc/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/di.xml @@ -11,6 +11,7 @@ <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product"> <arguments> <argument name="collectionProcessor" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor</argument> + <argument name="layer" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor</argument> </arguments> </type> <type name="Magento\EavGraphQl\Model\Resolver\Query\Type"> diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index 4ee27a953a628..cf42ed0c4ed6e 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -54,22 +54,16 @@ </argument> </arguments> </type> - <type name="Magento\Catalog\Model\Layer\Resolver"> + <type name="Magento\CatalogGraphQl\Model\Layer\Context"> <arguments> - <argument name="layersPool" xsi:type="array"> - <item name="graphql_category" xsi:type="string">Magento\CatalogGraphQl\Model\Layer\Category</item> - <item name="graphql_search" xsi:type="string">Magento\CatalogGraphQl\Model\Layer\Search</item> - </argument> - </arguments> - </type> - <type name="Magento\CatalogGraphQl\Model\Layer\Search"> - <arguments> - <argument name="context" xsi:type="object">Magento\Catalog\Model\Layer\Search\Context</argument> + <argument name="collectionProvider" xsi:type="object">Magento\CatalogGraphQl\Model\Layer\CollectionProvider</argument> + <argument name="stateKey" xsi:type="object">Magento\Catalog\Model\Layer\Category\StateKey</argument> + <argument name="collectionFilter" xsi:type="object">Magento\Catalog\Model\Layer\Category\CollectionFilter</argument> </arguments> </type> - <type name="Magento\CatalogGraphQl\Model\Layer\Category"> + <type name="Magento\Catalog\Model\Layer\Search"> <arguments> - <argument name="context" xsi:type="object">Magento\Catalog\Model\Layer\Category\Context</argument> + <argument name="context" xsi:type="object">Magento\CatalogGraphQl\Model\Layer\Context</argument> </arguments> </type> </config> diff --git a/app/code/Magento/CatalogSearchGraphQl/LICENSE.txt b/app/code/Magento/CatalogSearchGraphQl/LICENSE.txt new file mode 100644 index 0000000000000..49525fd99da9c --- /dev/null +++ b/app/code/Magento/CatalogSearchGraphQl/LICENSE.txt @@ -0,0 +1,48 @@ + +Open Software License ("OSL") v. 3.0 + +This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: + +Licensed under the Open Software License version 3.0 + + 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: + + 1. to reproduce the Original Work in copies, either alone or as part of a collective work; + + 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; + + 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License; + + 4. to perform the Original Work publicly; and + + 5. to display the Original Work publicly. + + 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. + + 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. + + 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. + + 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). + + 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. + + 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. + + 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. + + 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including 'fair use' or 'fair dealing'). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). + + 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. + + 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. + + 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. + + 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. + + 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. + + 16. Modification of This License. This License is Copyright (C) 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. \ No newline at end of file diff --git a/app/code/Magento/CatalogSearchGraphQl/LICENSE_AFL.txt b/app/code/Magento/CatalogSearchGraphQl/LICENSE_AFL.txt new file mode 100644 index 0000000000000..f39d641b18a19 --- /dev/null +++ b/app/code/Magento/CatalogSearchGraphQl/LICENSE_AFL.txt @@ -0,0 +1,48 @@ + +Academic Free License ("AFL") v. 3.0 + +This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: + +Licensed under the Academic Free License version 3.0 + + 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: + + 1. to reproduce the Original Work in copies, either alone or as part of a collective work; + + 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; + + 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor's reserved rights and remedies, in this Academic Free License; + + 4. to perform the Original Work publicly; and + + 5. to display the Original Work publicly. + + 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. + + 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. + + 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. + + 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). + + 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. + + 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. + + 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. + + 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). + + 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. + + 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. + + 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. + + 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. + + 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. + + 16. Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. diff --git a/app/code/Magento/CatalogSearchGraphQl/README.md b/app/code/Magento/CatalogSearchGraphQl/README.md new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/app/code/Magento/CatalogSearchGraphQl/composer.json b/app/code/Magento/CatalogSearchGraphQl/composer.json new file mode 100644 index 0000000000000..f98e932750cd3 --- /dev/null +++ b/app/code/Magento/CatalogSearchGraphQl/composer.json @@ -0,0 +1,28 @@ +{ + "name": "magento/module-catalog-search-graph-ql", + "description": "N/A", + "config": { + "sort-packages": true + }, + "require": { + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "magento/framework": "100.3.*", + "magento/module-catalog-search": "100.3.*", + "magento/module-eav": "100.3.*", + "magento/module-search": "100.3.*" + }, + "type": "magento2-module", + "version": "100.3.0-dev", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\CatalogSearchGraphQl\\": "" + } + } +} diff --git a/app/code/Magento/CatalogSearchGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogSearchGraphQl/etc/graphql/di.xml new file mode 100644 index 0000000000000..46464d2bb90f7 --- /dev/null +++ b/app/code/Magento/CatalogSearchGraphQl/etc/graphql/di.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <!--<virtualType name="Magento\Catalog\Model\Layer\Search\Context" type="Magento\Catalog\Model\Layer\Context">--> + <!--<arguments>--> + <!--<argument name="collectionProvider" xsi:type="object">Magento\CatalogGraphQl\Model\Layer\CollectionProvider</argument>--> + <!--</arguments>--> + <!--</virtualType>--> + <!--<virtualType name="Magento\Catalog\Model\Layer\Category\Context" type="Magento\Catalog\Model\Layer\Context">--> + <!--<arguments>--> + <!--<argument name="collectionProvider" xsi:type="object">Magento\CatalogGraphQl\Model\Layer\CollectionProvider</argument>--> + <!--</arguments>--> + <!--</virtualType>--> + <virtualType name="Magento\CatalogSearch\Model\Layer\Search\Context" type="Magento\Catalog\Model\Layer\Search\Context"> + <arguments> + <argument name="collectionProvider" xsi:type="object">Magento\CatalogGraphQl\Model\Layer\CollectionProvider</argument> + </arguments> + </virtualType> + <virtualType name="Magento\CatalogSearch\Model\Layer\Category\Context" type="Magento\Catalog\Model\Layer\Search\Context"> + <arguments> + <argument name="collectionProvider" xsi:type="object">Magento\CatalogGraphQl\Model\Layer\CollectionProvider</argument> + </arguments> + </virtualType> +</config> diff --git a/app/code/Magento/CatalogSearchGraphQl/etc/module.xml b/app/code/Magento/CatalogSearchGraphQl/etc/module.xml new file mode 100644 index 0000000000000..d6cdcc10be3fb --- /dev/null +++ b/app/code/Magento/CatalogSearchGraphQl/etc/module.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> + <module name="Magento_CatalogSearchGraphQl" > + <sequence> + <module name="Magento_GraphQl"/> + <module name="Magento_CatalogGraphQl"/> + <module name="Magento_CatalogSearch"/> + </sequence> + </module> +</config> diff --git a/app/code/Magento/CatalogSearchGraphQl/registration.php b/app/code/Magento/CatalogSearchGraphQl/registration.php new file mode 100644 index 0000000000000..2d4f8afb2897d --- /dev/null +++ b/app/code/Magento/CatalogSearchGraphQl/registration.php @@ -0,0 +1,9 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use \Magento\Framework\Component\ComponentRegistrar; + +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_CatalogSearchGraphQl', __DIR__); From 982728b29db0c5733840b167cf9d96dedd79602f Mon Sep 17 00:00:00 2001 From: Leonid Poluyanov <lpoluyanov@magento.com> Date: Thu, 22 Mar 2018 16:22:57 +0200 Subject: [PATCH 156/668] MAGETWO-89417: [2.3.x][Functional-Tests] - AdminSwitchWYSIWYGOptionsCest fails on 2.3-develop --- .../Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml index 7deb63e025ee6..390f0af302c6c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml @@ -25,6 +25,7 @@ <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> </before> <amOnPage url="{{ConfigurationStoresPage.url}}" stepKey="navigateToWYSIWYGConfigPage1"/> + <waitForPageLoad stepKey="wait1"/> <conditionalClick stepKey="expandWYSIWYGOptions1" selector="{{ContentManagementSection.WYSIWYGOptions}}" dependentSelector="{{ContentManagementSection.CheckIfTabExpand}}" visible="true" /> <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox1" /> <uncheckOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="uncheckUseSystemValue1"/> @@ -33,7 +34,7 @@ <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions1" /> <click selector="{{ContentManagementSection.Save}}" stepKey="clickSaveConfig1" /> <amOnPage url="{{CmsNewPagePage.url}}" stepKey="navigateToPage1"/> - <waitForPageLoad stepKey="wait1"/> + <waitForPageLoad stepKey="wait2"/> <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle1"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab1" /> <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> @@ -52,6 +53,7 @@ <!--see widget on Storefront--> <see userInput="Hello TinyMCE4!" stepKey="seeContent1"/> <amOnPage url="{{ConfigurationStoresPage.url}}" stepKey="navigateToWYSIWYGConfigPage2"/> + <waitForPageLoad stepKey="wait4"/> <conditionalClick stepKey="expandWYSIWYGOptions" selector="{{ContentManagementSection.WYSIWYGOptions}}" dependentSelector="{{ContentManagementSection.CheckIfTabExpand}}" visible="true" /> <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox2" /> <uncheckOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="uncheckUseSystemValue2"/> @@ -60,7 +62,7 @@ <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions2" /> <click selector="{{ContentManagementSection.Save}}" stepKey="clickSaveConfig2" /> <amOnPage url="{{CmsNewPagePage.url}}" stepKey="navigateToPage2"/> - <waitForPageLoad stepKey="wait2"/> + <waitForPageLoad stepKey="wait5"/> <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle2"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab2" /> <waitForElementVisible selector="{{TinyMCESection.TinyMCE3}}" stepKey="waitForTinyMCE3"/> @@ -75,7 +77,7 @@ <click selector="{{CmsNewPagePageActionsSection.savePage}}" stepKey="clickSavePage2"/> <!-- Go to storefront cms page, assert cms content --> <amOnPage url="{{simpleCmsPage.identifier}}" stepKey="amOnPageTestPage2"/> - <waitForPageLoad stepKey="wait4" /> + <waitForPageLoad stepKey="wait6" /> <!--see widget on Storefront--> <see userInput="Hello TinyMCE3!" stepKey="seeContent2"/> <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4" /> From 6731292a7ea2dc043ce3cd8771ebf25131905924 Mon Sep 17 00:00:00 2001 From: Leonid Poluyanov <lpoluyanov@magento.com> Date: Thu, 22 Mar 2018 16:23:26 +0200 Subject: [PATCH 157/668] MAGETWO-89417: [2.3.x][Functional-Tests] - AdminSwitchWYSIWYGOptionsCest fails on 2.3-develop --- .../FunctionalTest/Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml index 390f0af302c6c..20514f54727fe 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml @@ -16,8 +16,6 @@ <title value="Admin are able to switch between versions of TinyMCE."/> <description value="Admin are able to switch between versions of TinyMCE."/> <severity value="CRITICAL"/> - <group value="skip"/> - <!-- Skipped; see MAGETWO-89417 --> <testCaseId value="MAGETWO-82936"/> </annotations> <before> From 7d512766bd2f3235b2aeeb5a513a2c59d76b1788 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Wed, 7 Mar 2018 11:47:40 +0200 Subject: [PATCH 158/668] MAGETWO-86332: Issues #10559 - Extend swatch using mixins (M2.2) #12929 (cherry picked from commit 10c9417) --- .../Swatches/Block/Product/Renderer/Listing/Configurable.php | 1 + .../Unit/Block/Product/Renderer/Listing/ConfigurableTest.php | 1 + 2 files changed, 2 insertions(+) diff --git a/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php b/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php index 54943498ee629..6e690805af18f 100644 --- a/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php +++ b/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php @@ -12,6 +12,7 @@ * * @api * @since 100.0.2 + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Configurable extends \Magento\Swatches\Block\Product\Renderer\Configurable { diff --git a/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php b/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php index 77369ad12fd9f..df5e4f8c51cb9 100644 --- a/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php @@ -9,6 +9,7 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyFields) */ class ConfigurableTest extends \PHPUnit\Framework\TestCase { From 0044fef110a1f17eab1be8efde090be2320729bf Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 6 Mar 2018 16:02:45 +0200 Subject: [PATCH 159/668] MAGETWO-86332: Issues #10559 - Extend swatch using mixins (M2.2) #12929 (cherry picked from commit 8441fbc) --- .../Block/Product/View/Type/Configurable.php | 42 +++------- .../Type/Configurable/Variations/Prices.php | 51 ++++++++++++ .../Product/View/Type/ConfigurableTest.php | 66 ++++++++------- .../Configurable/Variations/PricesTest.php | 60 ++++++++++++++ .../Product/Renderer/Listing/Configurable.php | 81 ++++++++++++++++++- .../Renderer/Listing/ConfigurableTest.php | 33 ++++++++ 6 files changed, 273 insertions(+), 60 deletions(-) create mode 100644 app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Variations/Prices.php create mode 100644 app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/Configurable/Variations/PricesTest.php diff --git a/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php index b433d47b421dd..2502b79921e99 100644 --- a/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php @@ -67,13 +67,18 @@ class Configurable extends \Magento\Catalog\Block\Product\View\AbstractView /** * @var Format */ - protected $localeFormat; + private $localeFormat; /** * @var Session */ private $customerSession; + /** + * @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices + */ + private $variationPrices; + /** * @param \Magento\Catalog\Block\Product\Context $context * @param \Magento\Framework\Stdlib\ArrayUtils $arrayUtils @@ -86,6 +91,7 @@ class Configurable extends \Magento\Catalog\Block\Product\View\AbstractView * @param array $data * @param Format|null $localeFormat * @param Session|null $customerSession + * @param \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices|null $variationPrices * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -99,7 +105,8 @@ public function __construct( ConfigurableAttributeData $configurableAttributeData, array $data = [], Format $localeFormat = null, - Session $customerSession = null + Session $customerSession = null, + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices $variationPrices = null ) { $this->priceCurrency = $priceCurrency; $this->helper = $helper; @@ -109,6 +116,9 @@ public function __construct( $this->configurableAttributeData = $configurableAttributeData; $this->localeFormat = $localeFormat ?: ObjectManager::getInstance()->get(Format::class); $this->customerSession = $customerSession ?: ObjectManager::getInstance()->get(Session::class); + $this->variationPrices = $variationPrices ?: ObjectManager::getInstance()->get( + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices::class + ); parent::__construct( $context, @@ -220,7 +230,7 @@ public function getJsonConfig() 'currencyFormat' => $store->getCurrentCurrency()->getOutputFormat(), 'optionPrices' => $this->getOptionPrices(), 'priceFormat' => $this->localeFormat->getPriceFormat(), - 'prices' => $this->getPrices(), + 'prices' => $this->variationPrices->getFormattedPrices($this->getProduct()->getPriceInfo()), 'productId' => $currentProduct->getId(), 'chooseText' => __('Choose an Option...'), 'images' => $this->getOptionImages(), @@ -235,32 +245,6 @@ public function getJsonConfig() return $this->jsonEncoder->encode($config); } - - /** - * Get product prices for configurable variations - * - * @return array - * @since 100.2.0 - */ - protected function getPrices() - { - $currentProduct = $this->getProduct(); - - $regularPrice = $currentProduct->getPriceInfo()->getPrice('regular_price'); - $finalPrice = $currentProduct->getPriceInfo()->getPrice('final_price'); - - return [ - 'oldPrice' => [ - 'amount' => $this->localeFormat->getNumber($regularPrice->getAmount()->getValue()), - ], - 'basePrice' => [ - 'amount' => $this->localeFormat->getNumber($finalPrice->getAmount()->getBaseAmount()), - ], - 'finalPrice' => [ - 'amount' => $this->localeFormat->getNumber($finalPrice->getAmount()->getValue()), - ], - ]; - } /** * Get product images for configurable variations diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Variations/Prices.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Variations/Prices.php new file mode 100644 index 0000000000000..a60730b06fad2 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Variations/Prices.php @@ -0,0 +1,51 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations; + +/** + * Configurable product variation prices. + */ +class Prices +{ + /** + * @var \Magento\Framework\Locale\Format + */ + private $localeFormat; + + /** + * Prices constructor. + * @param \Magento\Framework\Locale\Format $localeFormat + */ + public function __construct(\Magento\Framework\Locale\Format $localeFormat) + { + $this->localeFormat = $localeFormat; + } + + /** + * Get product prices for configurable variations + * + * @param \Magento\Framework\Pricing\PriceInfo\Base $priceInfo + * @return array + */ + public function getFormattedPrices(\Magento\Framework\Pricing\PriceInfo\Base $priceInfo) + { + $regularPrice = $priceInfo->getPrice('regular_price'); + $finalPrice = $priceInfo->getPrice('final_price'); + + return [ + 'oldPrice' => [ + 'amount' => $this->localeFormat->getNumber($regularPrice->getAmount()->getValue()), + ], + 'basePrice' => [ + 'amount' => $this->localeFormat->getNumber($finalPrice->getAmount()->getBaseAmount()), + ], + 'finalPrice' => [ + 'amount' => $this->localeFormat->getNumber($finalPrice->getAmount()->getValue()), + ], + ]; + } +} diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Product/View/Type/ConfigurableTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Product/View/Type/ConfigurableTest.php index db3c30e3b4e33..b45306d670bff 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Product/View/Type/ConfigurableTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Product/View/Type/ConfigurableTest.php @@ -78,6 +78,11 @@ class ConfigurableTest extends \PHPUnit\Framework\TestCase */ private $customerSession; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $variationPricesMock; + protected function setUp() { $this->mockContextObject(); @@ -144,6 +149,10 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); + $this->variationPricesMock = $this->createMock( + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices::class + ); + $this->block = new \Magento\ConfigurableProduct\Block\Product\View\Type\Configurable( $this->context, $this->arrayUtils, @@ -155,7 +164,8 @@ protected function setUp() $this->configurableAttributeData, [], $this->localeFormat, - $this->customerSession + $this->customerSession, + $this->variationPricesMock ); } @@ -260,12 +270,8 @@ public function testGetJsonConfig() 'getAmount', ]) ->getMockForAbstractClass(); - $priceMock->expects($this->any()) - ->method('getAmount') - ->willReturn($amountMock); - + $priceMock->expects($this->any())->method('getAmount')->willReturn($amountMock); $tierPriceMock = $this->getTierPriceMock($amountMock, $priceQty, $percentage); - $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) ->disableOriginalConstructor() ->getMock(); @@ -283,27 +289,16 @@ public function testGetJsonConfig() ['tier_price', $tierPriceMock], ]); - $productMock->expects($this->any()) - ->method('getTypeInstance') - ->willReturn($productTypeMock); - $productMock->expects($this->any()) - ->method('getPriceInfo') - ->willReturn($priceInfoMock); - $productMock->expects($this->any()) - ->method('isSaleable') - ->willReturn(true); - $productMock->expects($this->any()) - ->method('getId') - ->willReturn($productId); + $productMock->expects($this->any())->method('getTypeInstance')->willReturn($productTypeMock); + $productMock->expects($this->any())->method('getPriceInfo')->willReturn($priceInfoMock); + $productMock->expects($this->any())->method('isSaleable')->willReturn(true); + $productMock->expects($this->any())->method('getId')->willReturn($productId); $this->helper->expects($this->any()) ->method('getOptions') ->with($productMock, [$productMock]) ->willReturn([]); - - $this->product->expects($this->any()) - ->method('getSkipSaleableCheck') - ->willReturn(true); + $this->product->expects($this->any())->method('getSkipSaleableCheck')->willReturn(true); $attributesData = [ 'attributes' => [], @@ -315,9 +310,7 @@ public function testGetJsonConfig() ->with($productMock, []) ->willReturn($attributesData); - $this->localeFormat->expects($this->any()) - ->method('getPriceFormat') - ->willReturn([]); + $this->localeFormat->expects($this->atLeastOnce())->method('getPriceFormat')->willReturn([]); $this->localeFormat->expects($this->any()) ->method('getNumber') ->willReturnMap([ @@ -326,16 +319,29 @@ public function testGetJsonConfig() [$percentage, $percentage], ]); + $this->variationPricesMock->expects($this->once()) + ->method('getFormattedPrices') + ->with($priceInfoMock) + ->willReturn( + [ + 'oldPrice' => [ + 'amount' => $amount, + ], + 'basePrice' => [ + 'amount' => $amount, + ], + 'finalPrice' => [ + 'amount' => $amount, + ], + ] + ); + $expectedArray = $this->getExpectedArray($productId, $amount, $priceQty, $percentage); $expectedJson = json_encode($expectedArray); - $this->jsonEncoder->expects($this->once()) - ->method('encode') - ->with($expectedArray) - ->willReturn($expectedJson); + $this->jsonEncoder->expects($this->once())->method('encode')->with($expectedArray)->willReturn($expectedJson); $this->block->setData('product', $productMock); - $result = $this->block->getJsonConfig(); $this->assertEquals($expectedJson, $result); } diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/Configurable/Variations/PricesTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/Configurable/Variations/PricesTest.php new file mode 100644 index 0000000000000..6d7067666989c --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/Configurable/Variations/PricesTest.php @@ -0,0 +1,60 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\ConfigurableProduct\Test\Unit\Model\Product\Type\Configurable\Variations; + +use PHPUnit\Framework\TestCase; + +class PricesTest extends TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $localeFormatMock; + + /** + * @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices + */ + private $model; + + protected function setUp() + { + $this->localeFormatMock = $this->createMock(\Magento\Framework\Locale\Format::class); + $this->model = new \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices( + $this->localeFormatMock + ); + } + + public function testGetFormattedPrices() + { + $expected = [ + 'oldPrice' => [ + 'amount' => 500 + ], + 'basePrice' => [ + 'amount' => 1000 + ], + 'finalPrice' => [ + 'amount' => 500 + ] + ]; + $priceInfoMock = $this->createMock(\Magento\Framework\Pricing\PriceInfo\Base::class); + $priceMock = $this->createMock(\Magento\Framework\Pricing\Price\PriceInterface::class); + $priceInfoMock->expects($this->atLeastOnce())->method('getPrice')->willReturn($priceMock); + + $amountMock = $this->createMock(\Magento\Framework\Pricing\Amount\AmountInterface::class); + $amountMock->expects($this->atLeastOnce())->method('getValue')->willReturn(500); + $amountMock->expects($this->atLeastOnce())->method('getBaseAmount')->willReturn(1000); + $priceMock->expects($this->atLeastOnce())->method('getAmount')->willReturn($amountMock); + + $this->localeFormatMock->expects($this->atLeastOnce()) + ->method('getNumber') + ->withConsecutive([500], [1000], [500]) + ->will($this->onConsecutiveCalls(500, 1000, 500)); + + $this->assertEquals($expected, $this->model->getFormattedPrices($priceInfoMock)); + } +} diff --git a/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php b/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php index 6e690805af18f..85633475205ed 100644 --- a/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php +++ b/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php @@ -5,7 +5,19 @@ */ namespace Magento\Swatches\Block\Product\Renderer\Listing; +use Magento\Catalog\Block\Product\Context; +use Magento\Catalog\Helper\Product as CatalogProduct; use Magento\Catalog\Model\Product; +use Magento\ConfigurableProduct\Helper\Data; +use Magento\ConfigurableProduct\Model\ConfigurableAttributeData; +use Magento\Customer\Helper\Session\CurrentCustomer; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Json\EncoderInterface; +use Magento\Framework\Pricing\PriceCurrencyInterface; +use Magento\Framework\Stdlib\ArrayUtils; +use Magento\Swatches\Helper\Data as SwatchData; +use Magento\Swatches\Helper\Media; +use Magento\Swatches\Model\SwatchAttributesProvider; /** * Swatch renderer block in Category page @@ -16,6 +28,71 @@ */ class Configurable extends \Magento\Swatches\Block\Product\Renderer\Configurable { + /** + * @var \Magento\Framework\Locale\Format + */ + private $localeFormat; + + /** + * @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices + */ + private $variationPrices; + + /** + * @param Context $context + * @param ArrayUtils $arrayUtils + * @param EncoderInterface $jsonEncoder + * @param Data $helper + * @param CatalogProduct $catalogProduct + * @param CurrentCustomer $currentCustomer + * @param PriceCurrencyInterface $priceCurrency + * @param ConfigurableAttributeData $configurableAttributeData + * @param SwatchData $swatchHelper + * @param Media $swatchMediaHelper + * @param array $data other data + * @param SwatchAttributesProvider $swatchAttributesProvider + * @param \Magento\Framework\Locale\Format|null $localeFormat + * @param \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices|null $variationPrices + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ + public function __construct( + Context $context, + ArrayUtils $arrayUtils, + EncoderInterface $jsonEncoder, + Data $helper, + CatalogProduct $catalogProduct, + CurrentCustomer $currentCustomer, + PriceCurrencyInterface $priceCurrency, + ConfigurableAttributeData $configurableAttributeData, + SwatchData $swatchHelper, + Media $swatchMediaHelper, + array $data = [], + SwatchAttributesProvider $swatchAttributesProvider = null, + \Magento\Framework\Locale\Format $localeFormat = null, + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices $variationPrices = null + ) { + parent::__construct( + $context, + $arrayUtils, + $jsonEncoder, + $helper, + $catalogProduct, + $currentCustomer, + $priceCurrency, + $configurableAttributeData, + $swatchHelper, + $swatchMediaHelper, + $data, + $swatchAttributesProvider + ); + $this->localeFormat = $localeFormat ?: ObjectManager::getInstance()->get( + \Magento\Framework\Locale\Format::class + ); + $this->variationPrices = $variationPrices ?: ObjectManager::getInstance()->get( + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices::class + ); + } + /** * @return string */ @@ -85,7 +162,9 @@ public function getPriceFormatJson() */ public function getPricesJson() { - return $this->jsonEncoder->encode($this->getPrices()); + return $this->jsonEncoder->encode( + $this->variationPrices->getFormattedPrices($this->getProduct()->getPriceInfo()) + ); } /** diff --git a/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php b/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php index df5e4f8c51cb9..6b72422d05014 100644 --- a/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php @@ -58,6 +58,9 @@ class ConfigurableTest extends \PHPUnit\Framework\TestCase /** @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject */ private $urlBuilder; + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $variationPricesMock; + public function setUp() { $this->arrayUtils = $this->createMock(\Magento\Framework\Stdlib\ArrayUtils::class); @@ -76,6 +79,9 @@ public function setUp() $this->scopeConfig = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); $this->imageHelper = $this->createMock(\Magento\Catalog\Helper\Image::class); $this->urlBuilder = $this->createMock(\Magento\Framework\UrlInterface::class); + $this->variationPricesMock = $this->createMock( + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices::class + ); $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->configurable = $objectManagerHelper->getObject( @@ -94,6 +100,7 @@ public function setUp() 'priceCurrency' => $this->priceCurrency, 'configurableAttributeData' => $this->configurableAttributeData, 'data' => [], + 'variationPrices' => $this->variationPricesMock ] ); } @@ -202,4 +209,30 @@ private function prepareGetJsonSwatchConfig() $this->helper->expects($this->any())->method('getAllowAttributes')->with($this->product) ->willReturn([$attribute1]); } + + public function testGetPricesJson() + { + $expectedPrices = [ + 'oldPrice' => [ + 'amount' => 10, + ], + 'basePrice' => [ + 'amount' => 15, + ], + 'finalPrice' => [ + 'amount' => 20, + ], + ]; + + $priceInfoMock = $this->createMock(\Magento\Framework\Pricing\PriceInfo\Base::class); + $this->configurable->setProduct($this->product); + $this->product->expects($this->once())->method('getPriceInfo')->willReturn($priceInfoMock); + $this->variationPricesMock->expects($this->once()) + ->method('getFormattedPrices') + ->with($priceInfoMock) + ->willReturn($expectedPrices); + + $this->jsonEncoder->expects($this->once())->method('encode')->with($expectedPrices); + $this->configurable->getPricesJson(); + } } From 3fe794a3e989e3077bdf4647ae238e4924dbe99c Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" <a.vasiliev@sam-solutions.biz> Date: Thu, 22 Mar 2018 16:57:06 +0200 Subject: [PATCH 160/668] fix catching exception for unresolved inputParams, save rejected operation to magento_operation table, change AsyncResponse operation list id from key index to OperationID --- .../Rest/Async/InputParamsResolver.php | 15 +++- .../Model/MessageQueue/MassSchedule.php | 79 +++++++++++++------ 2 files changed, 69 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/Async/InputParamsResolver.php b/app/code/Magento/WebapiAsync/Controller/Rest/Async/InputParamsResolver.php index 9a8232e30a147..855002cbfd789 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/Async/InputParamsResolver.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/Async/InputParamsResolver.php @@ -91,10 +91,20 @@ public function resolve() //simple check if async request have single or bulk entities if (array_key_exists(0, $inputData)) { foreach ($inputData as $key => $singleParams) { - $webapiResolvedParams[$key] = $this->resolveParams($singleParams); + try { + $webapiResolvedParams[$key] = $this->resolveParams($singleParams); + } catch (\Exception $e) { + //return input request data when failed to process rejected type in MassSchedule + $webapiResolvedParams[$key] = $singleParams; + } } } else {//single item request - $webapiResolvedParams[] = $this->resolveParams($inputData); + try { + $webapiResolvedParams[] = $this->resolveParams($inputData); + } catch (\Exception $e) { + //return input request data when failed to process rejected type in MassSchedule + $webapiResolvedParams[] = $inputData; + } } return $webapiResolvedParams; @@ -132,6 +142,7 @@ private function resolveParams($inputData) $inputData = $this->paramsOverrider->override($inputData, $route->getParameters()); $inputParams = $this->serviceInputProcessor->process($serviceClassName, $serviceMethodName, $inputData); + return $inputParams; } } diff --git a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php index 221a149a8c85d..83fc4f71a1381 100644 --- a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php +++ b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php @@ -175,39 +175,33 @@ public function publishMass($topicName, $entitiesArray, $groupId = null) $operations = []; $requestItems = []; - foreach ($entitiesArray as $key => $entityParams) { + foreach ($entitiesArray as $entityParams) { /** @var \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterface $requestItem */ $requestItem = $this->itemStatusInterfaceFactory->create(); try { $this->messageValidator->validate($topicName, $entityParams); $data = $this->messageEncoder->encode($topicName, $entityParams); - - $serializedData = [ - 'entity_id' => null, - 'entity_link' => '', - 'meta_information' => $data, - ]; - $data = [ - 'data' => [ - OperationInterface::BULK_ID => $groupId, - OperationInterface::TOPIC_NAME => $topicName, - OperationInterface::SERIALIZED_DATA => $this->jsonHelper->serialize($serializedData), - OperationInterface::STATUS => OperationInterface::STATUS_TYPE_OPEN, - ], - ]; - - /** @var \Magento\AsynchronousOperations\Api\Data\OperationInterface $operation */ - $operation = $this->operationFactory->create($data); - $operations[] = $this->entityManager->save($operation); - - $requestItem->setId($key); - $requestItem->setStatus(ItemStatusInterface::STATUS_ACCEPTED); + $operationStatus = OperationInterface::STATUS_TYPE_OPEN; } catch (\Exception $exception) { - $requestItem->setId($key); + $data = $entityParams; + //TODO after merge with BulkApi Status need change cons from OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED to OperationInterface::STATUS_TYPE_REJECTED + $operationStatus = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED; + } + + $operation = $this->saveOperation($groupId, $topicName, $data, $operationStatus); + if (!isset($exception)) { + $operations[] = $operation; + } + + $requestItem->setId($operation->getId()); + $requestItem->setStatus(ItemStatusInterface::STATUS_ACCEPTED); + + if (isset($exception)) { $requestItem->setStatus(ItemStatusInterface::STATUS_REJECTED); $requestItem->setErrorMessage($exception); $requestItem->setErrorCode($exception); + unset($exception); } $requestItems[] = $requestItem; @@ -227,4 +221,43 @@ public function publishMass($topicName, $entitiesArray, $groupId = null) return $asyncResponse; } + + /** + * @param string $groupId + * @param string $topicName + * @param mixed $data + * @param int $operationStatus + * @param null $error + * @param null $errorCode + * @return \Magento\AsynchronousOperations\Api\Data\OperationInterface + */ + private function saveOperation( + $groupId, + $topicName, + $data, + $operationStatus = OperationInterface::STATUS_TYPE_OPEN, + $error = null, + $errorCode = null + ) { + $serializedData = [ + 'entity_id' => null, + 'entity_link' => '', + 'meta_information' => $data, + ]; + $data = [ + 'data' => [ + OperationInterface::BULK_ID => $groupId, + OperationInterface::TOPIC_NAME => $topicName, + OperationInterface::SERIALIZED_DATA => $this->jsonHelper->serialize($serializedData), + OperationInterface::STATUS => $operationStatus, + OperationInterface::RESULT_MESSAGE => $error, + OperationInterface::ERROR_CODE => $errorCode, + ], + ]; + + /** @var \Magento\AsynchronousOperations\Api\Data\OperationInterface $operation */ + $operation = $this->operationFactory->create($data); + + return $this->entityManager->save($operation); + } } From c5549d705087ec8211b281566beed7cd3131e569 Mon Sep 17 00:00:00 2001 From: Ben Batschelet <bbatschelet@magento.com> Date: Thu, 22 Mar 2018 09:57:27 -0500 Subject: [PATCH 161/668] Move output buffering to bootstrap --- .../integration/framework/tests/unit/framework/bootstrap.php | 2 ++ .../unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/framework/tests/unit/framework/bootstrap.php b/dev/tests/integration/framework/tests/unit/framework/bootstrap.php index 94ca822568be1..ab3294df72b89 100644 --- a/dev/tests/integration/framework/tests/unit/framework/bootstrap.php +++ b/dev/tests/integration/framework/tests/unit/framework/bootstrap.php @@ -9,3 +9,5 @@ require_once $rootDir . '/app/bootstrap.php'; require_once $testsBaseDir . '/framework/autoload.php'; + +ob_start(); diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php index 2d56212ae443a..b6207f309ead9 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php @@ -9,7 +9,6 @@ */ namespace Magento\Test\Bootstrap; -ob_start(); class EnvironmentTest extends \PHPUnit\Framework\TestCase { /** From 8becb937f1dd4fbdb7825419e21d615f12c7b0a5 Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" <a.vasiliev@sam-solutions.biz> Date: Thu, 22 Mar 2018 17:02:32 +0200 Subject: [PATCH 162/668] save operation error message and code when rejected --- .../Model/MessageQueue/MassSchedule.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php index 83fc4f71a1381..1692a4c5b6cde 100644 --- a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php +++ b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php @@ -188,8 +188,19 @@ public function publishMass($topicName, $entitiesArray, $groupId = null) //TODO after merge with BulkApi Status need change cons from OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED to OperationInterface::STATUS_TYPE_REJECTED $operationStatus = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED; } - - $operation = $this->saveOperation($groupId, $topicName, $data, $operationStatus); + if (!isset($exception)) { + $operation = $this->saveOperation($groupId, $topicName, $data, $operationStatus); + } else { + $operation = + $this->saveOperation( + $groupId, + $topicName, + $data, + $operationStatus, + $exception->getMessage(), + $exception->getCode() + ); + } if (!isset($exception)) { $operations[] = $operation; } From 85c13c54166fef30494d4a4172211cf7d428da19 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Thu, 22 Mar 2018 12:20:21 -0500 Subject: [PATCH 163/668] MAGETWO-89082: Update composer dependencies --- lib/internal/Magento/Framework/Amqp/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Amqp/composer.json b/lib/internal/Magento/Framework/Amqp/composer.json index 2fa84f7ed3e5d..f92b3ec22cb5b 100644 --- a/lib/internal/Magento/Framework/Amqp/composer.json +++ b/lib/internal/Magento/Framework/Amqp/composer.json @@ -13,7 +13,7 @@ "require": { "magento/framework": "100.3.*", "php": "~7.1.3||~7.2.0", - "php-amqplib/php-amqplib": "2.5.*" + "php-amqplib/php-amqplib": "~2.7.0" }, "autoload": { "psr-4": { From e082ed1fbd33e4caf7c39639ff3043a4a9079d0f Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Thu, 22 Mar 2018 12:45:26 -0500 Subject: [PATCH 164/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - updated class namespace --- app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php index f668c66db0058..fe66dd657c5b0 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php +++ b/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\Webapi\Test\Unit\Controller; +namespace Magento\WebapiAsync\Test\Unit\Controller; use Magento\Authorization\Model\UserContextInterface; use Magento\Framework\Exception\AuthorizationException; From 4286bba5aa03f3901f5553460d0708e31b7759f6 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <apaliarush@magento.com> Date: Thu, 22 Mar 2018 15:35:08 -0500 Subject: [PATCH 165/668] MAGETWO-89492: Implement lazy loading for types during queries - Eliminated Type/Generator - Implemented lazy loading for Webonyx types and fields via closures --- .../Magento/GraphQl/Model/SchemaGenerator.php | 35 +++---- .../Magento/GraphQl/Model/Type/Generator.php | 48 ---------- .../GraphQl/Model/Type/GeneratorInterface.php | 21 ---- app/code/Magento/GraphQl/etc/di.xml | 1 - .../Framework/GraphQl/SchemaProvider.php | 27 +++--- .../Output/ElementMapper/Formatter/Fields.php | 96 ++++++++++++------- .../ElementMapper/Formatter/Interfaces.php | 2 +- .../GraphQl/Type/Output/OutputMapper.php | 44 ++++----- 8 files changed, 118 insertions(+), 156 deletions(-) delete mode 100644 app/code/Magento/GraphQl/Model/Type/Generator.php delete mode 100644 app/code/Magento/GraphQl/Model/Type/GeneratorInterface.php diff --git a/app/code/Magento/GraphQl/Model/SchemaGenerator.php b/app/code/Magento/GraphQl/Model/SchemaGenerator.php index ae73c5c6dab0a..20137ca00464a 100644 --- a/app/code/Magento/GraphQl/Model/SchemaGenerator.php +++ b/app/code/Magento/GraphQl/Model/SchemaGenerator.php @@ -9,19 +9,14 @@ use Magento\Framework\GraphQl\Type\SchemaFactory; use Magento\Framework\GraphQl\Type\Schema; -use Magento\GraphQl\Model\Type\Generator; use Magento\Framework\GraphQl\TypeFactory; +use Magento\Framework\GraphQl\Type\Output\OutputMapper; /** * Generate a query field and concrete types for GraphQL schema */ class SchemaGenerator implements SchemaGeneratorInterface { - /** - * @var Generator - */ - private $typeGenerator; - /** * @var TypeFactory */ @@ -33,18 +28,23 @@ class SchemaGenerator implements SchemaGeneratorInterface private $schemaFactory; /** - * @param Generator $typeGenerator + * @var OutputMapper + */ + private $outputMapper; + + /** * @param TypeFactory $typeFactory * @param SchemaFactory $schemaFactory + * @param OutputMapper $outputMapper */ public function __construct( - Generator $typeGenerator, TypeFactory $typeFactory, - SchemaFactory $schemaFactory + SchemaFactory $schemaFactory, + OutputMapper $outputMapper ) { - $this->typeGenerator = $typeGenerator; $this->typeFactory = $typeFactory; $this->schemaFactory = $schemaFactory; + $this->outputMapper = $outputMapper; } /** @@ -52,13 +52,14 @@ public function __construct( */ public function generate() : Schema { - $schemaConfig = $this->typeGenerator->generateTypes(); - - $config = $this->typeFactory->createObject([ - 'name' => 'Query', - 'fields' => $schemaConfig['fields'] - ]); - $schema = $this->schemaFactory->create(['query' => $config, 'types' => $schemaConfig['types']]); + $schema = $this->schemaFactory->create( + [ + 'query' => $this->outputMapper->getOutputType('Query'), + 'typeLoader' => function ($name) { + return $this->outputMapper->getOutputType($name); + } + ] + ); return $schema; } } diff --git a/app/code/Magento/GraphQl/Model/Type/Generator.php b/app/code/Magento/GraphQl/Model/Type/Generator.php deleted file mode 100644 index ee64b8be21158..0000000000000 --- a/app/code/Magento/GraphQl/Model/Type/Generator.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\GraphQl\Model\Type; - -use Magento\Framework\GraphQl\SchemaProvider; - -/** - * {@inheritdoc} - */ -class Generator implements GeneratorInterface -{ - /** - * @var SchemaProvider - */ - private $schemaProvider; - - /** - * @param SchemaProvider $schemaProvider - */ - public function __construct( - SchemaProvider $schemaProvider - ) { - $this->schemaProvider = $schemaProvider; - } - - /** - * {@inheritdoc} - */ - public function generateTypes() : array - { - $types = []; - foreach ($this->schemaProvider->getTypes() as $name => $type) { - if ($name == 'Query') { - continue; - } - $types[] = $type; - } - return [ - 'fields' => $this->schemaProvider->getQuery()->getFields(), - 'types' => $types - ]; - } -} diff --git a/app/code/Magento/GraphQl/Model/Type/GeneratorInterface.php b/app/code/Magento/GraphQl/Model/Type/GeneratorInterface.php deleted file mode 100644 index fd16152d88150..0000000000000 --- a/app/code/Magento/GraphQl/Model/Type/GeneratorInterface.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\GraphQl\Model\Type; - -/** - * Generate configured GraphQL type schema and top-level fields of base query object - */ -interface GeneratorInterface -{ - /** - * Generate type definitions for all fields of given GraphQl query or mutation name - * - * @return array Represented as ['fields' => ['fieldName' => Type, {...}], 'types' => Types[]] - */ - public function generateTypes() : array; -} diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 6a9a2914368f6..219137695e0a9 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -7,7 +7,6 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\GraphQl\Model\SchemaGeneratorInterface" type="Magento\GraphQl\Model\SchemaGenerator" /> - <preference for="Magento\GraphQl\Model\Type\GeneratorInterface" type="Magento\GraphQl\Model\Type\Generator" /> <preference for="Magento\GraphQl\Model\ResolverContextInterface" type="Magento\GraphQl\Model\ResolverContext" /> <preference for="Magento\Framework\GraphQl\Type\Entity\MapperInterface" type="Magento\Framework\GraphQl\Type\Entity\DefaultMapper"/> <preference for="Magento\Framework\GraphQl\Type\Enum\DataMapperInterface" type="Magento\Framework\GraphQl\Type\Enum\DefaultDataMapper"/> diff --git a/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php b/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php index 4129716fbe034..eb97bce694c10 100644 --- a/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php +++ b/lib/internal/Magento/Framework/GraphQl/SchemaProvider.php @@ -32,6 +32,11 @@ class SchemaProvider */ private $scalarTypes; + /** + * @var OutputType[] + */ + private $typeObjects; + /** * SchemaProvider constructor. * @param ConfigInterface $config @@ -55,24 +60,18 @@ public function __construct( */ public function getTypes() : array { - $types = []; + if ($this->typeObjects !== null) { + return $this->typeObjects; + } + + $this->typeObjects = []; foreach ($this->config->getDeclaredTypeNames() as $typeName) { if ($this->scalarTypes->isScalarType($typeName)) { - $types[$typeName] = $this->scalarTypes->getScalarTypeInstance($typeName); + $this->typeObjects[$typeName] = $this->scalarTypes->getScalarTypeInstance($typeName); } else { - $types[$typeName] = $this->outputMapper->getTypeObject($typeName); + $this->typeObjects[$typeName] = $this->outputMapper->getOutputType($typeName); } } - return $types; - } - - /** - * Retrieve the top-level Query type object containing all described queries for a client to consume. - * - * @return OutputType - */ - public function getQuery() : OutputType - { - return $this->outputMapper->getTypeObject('Query'); + return $this->typeObjects; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php index aa6afd11cef80..bf41a9dca74cb 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php @@ -3,7 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -declare(strict_types = 1); +declare(strict_types=1); namespace Magento\Framework\GraphQl\Type\Output\ElementMapper\Formatter; @@ -81,47 +81,79 @@ public function __construct( /** * {@inheritDoc} */ - public function format(TypeInterface $typeStructure, OutputType $outputType) : array + public function format(TypeInterface $typeStructure, OutputType $outputType): array { - $config = []; - /** @var Field $field */ - foreach ($typeStructure->getFields() as $field) { - if ($this->scalarTypes->isScalarType($field->getTypeName())) { - $type = $this->wrappedTypeProcessor->processScalarWrappedType($field); + $typeConfig = [ + 'fields' => function () use ($typeStructure, $outputType) { + $fieldsConfig = []; + foreach ($typeStructure->getFields() as $field) { + $fieldsConfig[$field->getName()] = $this->getFieldConfig($typeStructure, $outputType, $field); + } + return $fieldsConfig; + } + ]; + return $typeConfig; + } + + + /** + * Generate field type object. + * + * @param TypeInterface $typeStructure + * @param OutputType $outputType + * @param Field $field + * @return OutputType + */ + private function getFieldType(TypeInterface $typeStructure, OutputType $outputType, Field $field) + { + if ($this->scalarTypes->isScalarType($field->getTypeName())) { + $type = $this->wrappedTypeProcessor->processScalarWrappedType($field); + } else { + if ($typeStructure->getName() == $field->getTypeName()) { + $type = $outputType; } else { if ($typeStructure->getName() == $field->getTypeName()) { $type = $outputType; } else { - if ($typeStructure->getName() == $field->getTypeName()) { - $type = $outputType; - } else { - $type = $this->outputMapper->getTypeObject($field->getTypeName()); - } - - $type = $this->wrappedTypeProcessor->processWrappedType($field, $type); + $type = $this->outputMapper->getOutputType($field->getTypeName()); } - } - $config['fields'][$field->getName()] = [ - 'name' => $field->getName(), - 'type' => $type, - ]; - if (!empty($field->getDescription())) { - $config['fields'][$field->getName()]['description'] = $field->getDescription(); + $type = $this->wrappedTypeProcessor->processWrappedType($field, $type); } + } + return $type; + } + + /** + * Generate field config. + * + * @param TypeInterface $typeStructure + * @param OutputType $outputType + * @param Field $field + * @return array + */ + private function getFieldConfig(TypeInterface $typeStructure, OutputType $outputType, Field $field): array + { + $type = $this->getFieldType($typeStructure, $outputType, $field); + $fieldConfig = [ + 'name' => $field->getName(), + 'type' => $type, + ]; + + if (!empty($field->getDescription())) { + $fieldConfig['description'] = $field->getDescription(); + } - if ($field->getResolver() != null) { - /** @var ResolverInterface $resolver */ - $resolver = $this->objectManager->get($field->getResolver()); + if ($field->getResolver() != null) { + /** @var ResolverInterface $resolver */ + $resolver = $this->objectManager->get($field->getResolver()); - $config['fields'][$field->getName()]['resolve'] = - function ($value, $args, $context, $info) use ($resolver, $field) { - return $resolver->resolve($field, $value, $args, $context, $info); - }; - } - $config = $this->formatArguments($field, $config); + $fieldConfig['resolve'] = + function ($value, $args, $context, $info) use ($resolver, $field) { + return $resolver->resolve($field, $value, $args, $context, $info); + }; } - return $config; + return $this->formatArguments($field, $fieldConfig); } /** @@ -136,7 +168,7 @@ private function formatArguments(Field $field, array $config) foreach ($field->getArguments() as $argument) { $inputType = $this->inputMapper->getRepresentation($argument); - $config['fields'][$field->getName()]['args'][$argument->getName()] = $inputType; + $config['args'][$argument->getName()] = $inputType; } return $config; diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php index cbb4d74efb231..fafed17a8286f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php @@ -47,7 +47,7 @@ public function format(TypeInterface $typeStructure, OutputType $outputType) : a if ($typeStructure instanceof Type && !empty($typeStructure->getInterfaces())) { $interfaces = []; foreach ($typeStructure->getInterfaces() as $interface) { - $interfaces[$interface['interface']] = $this->outputMapper->getInterface($interface['interface']); + $interfaces[$interface['interface']] = $this->outputMapper->getOutputType($interface['interface']); } $config['interfaces'] = $interfaces; } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php index 44986663c3614..1f48293abec7a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/OutputMapper.php @@ -3,13 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -declare(strict_types = 1); +declare(strict_types=1); namespace Magento\Framework\GraphQl\Type\Output; use Magento\Framework\GraphQl\Config\ConfigInterface; use Magento\Framework\GraphQl\Type\Definition\OutputType; use Magento\Framework\GraphQl\TypeFactory; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Phrase; /** * Map type names to their output type/interface classes. @@ -21,6 +23,11 @@ class OutputMapper */ private $outputFactory; + /** + * @var OutputType[] + */ + private $outputTypes; + /** * @var TypeFactory */ @@ -47,31 +54,24 @@ public function __construct( } /** - * Return type object found based off type name input. + * Get GraphQL output type object by type name. * - * @param string $type + * @param string $typeName * @return OutputType + * @throws GraphQlInputException */ - public function getTypeObject(string $type) : OutputType - { - $configElement = $this->config->getTypeStructure($type); - return $this->outputFactory->create($configElement); - } - - /** - * Retrieve interface object if found, otherwise return null. - * - * @param string $type - * @return OutputInterfaceObject|null - */ - public function getInterface(string $type) : ?OutputInterfaceObject + public function getOutputType($typeName) { - $configElement = $this->config->getTypeStructure($type); - $instance = $this->outputFactory->create($configElement); - if ($instance instanceof OutputInterfaceObject) { - return $instance; - } else { - return null; + if (!isset($this->outputTypes[$typeName])) { + $configElement = $this->config->getTypeStructure($typeName); + $this->outputTypes[$typeName] = $this->outputFactory->create($configElement); + if (!($this->outputTypes[$typeName] instanceof OutputType)) { + throw new GraphQlInputException( + new Phrase("Type '{$typeName}' was requested but is not declared in the GraphQL schema.") + ); + } } + + return $this->outputTypes[$typeName]; } } From bc1ffc99ef894ccb0b8a35fd8623a9d4017618ed Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@magento.com> Date: Thu, 22 Mar 2018 16:50:45 -0500 Subject: [PATCH 166/668] MAGETWO-89366: Create integration or api tests - added missing use case for product filter --- .../GraphQl/Catalog/ProductSearchTest.php | 46 ++++++++++++ .../_files/product_in_multiple_categories.php | 75 +++++++++++++++++++ ...roduct_in_multiple_categories_rollback.php | 31 ++++++++ 3 files changed, 152 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_in_multiple_categories.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_in_multiple_categories_rollback.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php index 73de7ebb8c0ca..b666332d9a57d 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php @@ -6,6 +6,7 @@ namespace Magento\GraphQl\Catalog; +use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\GraphQlAbstract; @@ -445,6 +446,51 @@ public function testFilterProductsInNextPageSortedByNameASC() $this->assertEquals(2, $response['products']['page_info']['current_page']); } + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_in_multiple_categories.php + */ + public function testFilteringForProductInMultipleCategories() + { + $productSku = 'simple333'; + $query + = <<<QUERY +{ + products(filter:{sku:{eq:"{$productSku}"}}) + { + items{ + id + sku + name + attribute_set_id + category_ids + } + } +} + +QUERY; + + $response = $this->graphQlQuery($query); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); + /** @var ProductInterface $product */ + $product = $productRepository->get('simple333'); + $categoryIds = $product->getCategoryIds(); + foreach ($categoryIds as $index => $value) { + $categoryIds[$index] = (int)$value; + } + $this->assertNotEmpty($response['products']['items'][0]['category_ids'], "Category_ids must not be empty"); + $this->assertNotNull($response['products']['items'][0]['category_ids'], "categoy_ids must not be null"); + $this->assertEquals($categoryIds, $response['products']['items'][0]['category_ids']); + $assertionMap = [ + + ['response_field' => 'id', 'expected_value' => $product->getId()], + ['response_field' => 'sku', 'expected_value' => $product->getSku()], + ['response_field' => 'name', 'expected_value' => $product->getName()], + ['response_field' => 'attribute_set_id', 'expected_value' => $product->getAttributeSetId()] + ]; + $this->assertResponseFields($response['products']['items'][0], $assertionMap); + } + /** * Sorting by price in the DESC order from the filtered items with default pageSize * diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_in_multiple_categories.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_in_multiple_categories.php new file mode 100644 index 0000000000000..bf32217b04d22 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_in_multiple_categories.php @@ -0,0 +1,75 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +$category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Category::class); +$category->isObjectNew(true); +$category->setId( + 333 +)->setCreatedAt( + '2014-06-23 09:50:07' +)->setName( + 'Category 1' +)->setParentId( + 2 +)->setPath( + '1/2/3' +)->setLevel( + 2 +)->setAvailableSortBy( + 'name' +)->setDefaultSortBy( + 'name' +)->setIsActive( + true +)->setPosition( + 1 +)->setAvailableSortBy( + ['position'] +)->save(); + +$category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Category::class); +$category->isObjectNew(true); +$category->setId(4) + ->setName('Category 2') + ->setParentId(2) + ->setPath('1/2/4') + ->setLevel(2) + ->setAvailableSortBy('name') + ->setDefaultSortBy('name') + ->setIsActive(true) + ->setIsAnchor(true) + ->setPosition(1) + ->save(); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); +$product->setTypeId( + \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE +)->setId( + 333 +)->setAttributeSetId( + 4 +)->setStoreId( + 1 +)->setWebsiteIds( + [1] +)->setName( + 'Simple Product Three' +)->setSku( + 'simple333' +)->setPrice( + 10 +)->setWeight( + 18 +)->setStockData( + ['use_config_manage_stock' => 0] +)->setCategoryIds( + [333, 4] +)->setVisibility( + \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH +)->setStatus( + \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED +)->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_in_multiple_categories_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_in_multiple_categories_rollback.php new file mode 100644 index 0000000000000..70ea9c744cf96 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_in_multiple_categories_rollback.php @@ -0,0 +1,31 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); +$product->load(333); +if ($product->getId()) { + $product->delete(); +} + +/** @var $category \Magento\Catalog\Model\Category */ +$category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Category::class); +$category->load(333); +if ($category->getId()) { + $category->delete(); +} + +/** @var $category \Magento\Catalog\Model\Category */ +$category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Category::class); +$category->load(4); +if ($category->getId()) { + $category->delete(); +} \ No newline at end of file From e9550594f160ffa89abc112c4ed2e5aecba36259 Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Thu, 22 Mar 2018 21:46:09 -0500 Subject: [PATCH 167/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - changed exception handling in MassSchedule - added base test case class to test Async WebAPI --- .../Model/MessageQueue/MassSchedule.php | 8 +- .../Unit/Controller/PathProcessorTest.php | 18 +- .../Test/Unit/Controller/RestTest.php | 26 +-- .../EnvironmentPreconditionException.php | 11 ++ .../PreconditionFailedException.php | 11 ++ .../PublisherConsumerController.php | 161 ++++++++++++++++++ .../UseCase/QueueTestCaseAbstract.php | 103 ++++------- .../Model/MessageQueue}/BulkScheduleTest.php | 4 +- .../Model/WebapiAsyncBaseTestCase.php | 105 ++++++++++++ 9 files changed, 347 insertions(+), 100 deletions(-) create mode 100644 dev/tests/integration/framework/Magento/TestFramework/MessageQueue/EnvironmentPreconditionException.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PreconditionFailedException.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PublisherConsumerController.php rename {app/code/Magento/WebapiAsync/Test/ApiFunctional => dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue}/BulkScheduleTest.php (99%) create mode 100644 dev/tests/integration/testsuite/Magento/WebapiAsync/Model/WebapiAsyncBaseTestCase.php diff --git a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php index 3cb9be290738b..2a2f291a7e1c3 100644 --- a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php +++ b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php @@ -158,6 +158,7 @@ public function publishMass($topicName, $entitiesArray, $groupId = null) $operations = []; $requestItems = []; + $errors = []; foreach ($entitiesArray as $key => $entityParams) { /** @var \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterface $requestItem */ $requestItem = $this->itemStatusInterfaceFactory->create(); @@ -183,17 +184,20 @@ public function publishMass($topicName, $entitiesArray, $groupId = null) /** @var \Magento\AsynchronousOperations\Api\Data\OperationInterface $operation */ $operation = $this->operationFactory->create($data); $operations[] = $this->entityManager->save($operation); - $requestItem->setId($key); $requestItem->setStatus(ItemStatusInterface::STATUS_ACCEPTED); + $requestItems[] = $requestItem; } catch (\Exception $exception) { $requestItem->setId($key); $requestItem->setStatus(ItemStatusInterface::STATUS_REJECTED); $requestItem->setErrorMessage($exception); $requestItem->setErrorCode($exception); + $errors[] = $requestItem; } + } - $requestItems[] = $requestItem; + if (!empty($errors)) { + throw new \Magento\Framework\Webapi\Exception($errors); } $result = $this->bulkManagement->scheduleBulk($groupId, $operations, $bulkDescription, $userId); diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php index bc76a803d3cfb..e7c820026a065 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php +++ b/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php @@ -25,14 +25,14 @@ class PathProcessorTest extends \PHPUnit\Framework\TestCase protected function setUp() { $this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) - ->disableOriginalConstructor() - ->getMock(); + ->disableOriginalConstructor() + ->getMock(); $this->storeManagerMock->expects($this->once()) - ->method('getStores') - ->willReturn([ - $this->arbitraryStoreCode => 'store object', - 'default' => 'default store object', - ]); + ->method('getStores') + ->willReturn([ + $this->arbitraryStoreCode => 'store object', + 'default' => 'default store object', + ]); $this->model = new \Magento\Webapi\Controller\PathProcessor($this->storeManagerMock); } @@ -48,8 +48,8 @@ public function testAllStoreCode($storeCodeInPath, $storeCodeSet, $setCurrentSto $storeCodeInPath = !$storeCodeInPath ? : '/' . $storeCodeInPath; // add leading slash if store code not empty $inPath = 'rest' . $storeCodeInPath . $this->endpointPath; $this->storeManagerMock->expects($this->exactly($setCurrentStoreCallCtr)) - ->method('setCurrentStore') - ->with($storeCodeSet); + ->method('setCurrentStore') + ->with($storeCodeSet); $result = $this->model->process($inPath); $this->assertSame($this->endpointPath, $result); } diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php index fe66dd657c5b0..f964b1cba3069 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php +++ b/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php @@ -102,28 +102,28 @@ protected function setUp() $this->requestMock->expects($this->any())->method('getHttpHost')->willReturn('testHostName.com'); $this->responseMock = $this->getResponseMock(); $routerMock = $this->getMockBuilder(\Magento\Webapi\Controller\Rest\Router::class)->setMethods(['match']) - ->disableOriginalConstructor()->getMock(); + ->disableOriginalConstructor()->getMock(); $this->routeMock = $this->getRouteMock(); $this->serviceMock = $this->getMockBuilder(self::SERVICE_ID)->setMethods([self::SERVICE_METHOD]) - ->disableOriginalConstructor()->getMock(); + ->disableOriginalConstructor()->getMock(); $this->oauthServiceMock = $this->getMockBuilder(\Magento\Framework\Oauth\OauthInterface::class) - ->setMethods(['validateAccessTokenRequest'])->getMockForAbstractClass(); + ->setMethods(['validateAccessTokenRequest'])->getMockForAbstractClass(); $this->authorizationMock = $this->getMockBuilder(\Magento\Framework\Webapi\Authorization::class) - ->disableOriginalConstructor()->getMock(); + ->disableOriginalConstructor()->getMock(); $paramsOverriderMock = $this->getMockBuilder(\Magento\Webapi\Controller\Rest\ParamsOverrider::class) - ->setMethods(['overrideParams']) - ->disableOriginalConstructor()->getMock(); + ->setMethods(['overrideParams']) + ->disableOriginalConstructor()->getMock(); $dataObjectProcessorMock = $this->getMockBuilder(\Magento\Framework\Reflection\DataObjectProcessor::class) - ->disableOriginalConstructor() - ->setMethods(['getMethodReturnType']) - ->getMockForAbstractClass(); + ->disableOriginalConstructor() + ->setMethods(['getMethodReturnType']) + ->getMockForAbstractClass(); $layoutMock = $this->getMockBuilder(\Magento\Framework\View\LayoutInterface::class) - ->disableOriginalConstructor()->getMock(); + ->disableOriginalConstructor()->getMock(); $errorProcessorMock = $this->createMock(\Magento\Framework\Webapi\ErrorProcessor::class); $errorProcessorMock->expects($this->any())->method('maskException')->will($this->returnArgument(0)); @@ -131,7 +131,7 @@ protected function setUp() $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->serviceInputProcessorMock = $this->getMockBuilder(\Magento\Framework\Webapi\ServiceInputProcessor::class) - ->disableOriginalConstructor()->setMethods(['process'])->getMock(); + ->disableOriginalConstructor()->setMethods(['process'])->getMock(); $areaListMock = $this->createMock(\Magento\Framework\App\AreaList::class); $areaMock = $this->createMock(\Magento\Framework\App\AreaInterface::class); @@ -173,8 +173,8 @@ protected function setUp() $this->serviceMock->expects($this->any())->method(self::SERVICE_METHOD)->will($this->returnValue(null)); $dataObjectProcessorMock->expects($this->any())->method('getMethodReturnType') - ->with(self::SERVICE_ID, self::SERVICE_METHOD) - ->will($this->returnValue('null')); + ->with(self::SERVICE_ID, self::SERVICE_METHOD) + ->will($this->returnValue('null')); $paramsOverriderMock->expects($this->any())->method('overrideParams')->will($this->returnValue([])); diff --git a/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/EnvironmentPreconditionException.php b/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/EnvironmentPreconditionException.php new file mode 100644 index 0000000000000..474e7215bef2b --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/EnvironmentPreconditionException.php @@ -0,0 +1,11 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\TestFramework\MessageQueue; + +class EnvironmentPreconditionException extends \Exception +{ + +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PreconditionFailedException.php b/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PreconditionFailedException.php new file mode 100644 index 0000000000000..270e4e8c013de --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PreconditionFailedException.php @@ -0,0 +1,11 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\TestFramework\MessageQueue; + +class PreconditionFailedException extends \Exception +{ + +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PublisherConsumerController.php b/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PublisherConsumerController.php new file mode 100644 index 0000000000000..b580478644e18 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PublisherConsumerController.php @@ -0,0 +1,161 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\TestFramework\MessageQueue; + +use Magento\Framework\MessageQueue\PublisherInterface; +use Magento\Framework\OsInfo; + +class PublisherConsumerController +{ + /** + * @var string[] + */ + private $consumers = []; + + /** + * @var PublisherInterface + */ + private $publisher; + + /** + * @var string + */ + private $logFilePath; + + /** + * @var int|null + */ + private $maxMessages = null; + + /** + * @var OsInfo + */ + private $osInfo; + + public function __construct( + PublisherInterface $publisher, + OsInfo $osInfo, + $logFilePath, + $maxMessages, + $consumers, + $appInitParams + ) { + $this->consumers = $consumers; + $this->publisher = $publisher; + $this->logFilePath = $logFilePath; + $this->maxMessages = $maxMessages; + $this->osInfo = $osInfo; + } + + /** + * Initialize Environment and Consumers + * + * @throws EnvironmentPreconditionException + * @throws PreconditionFailedException + */ + public function initialize() + { + if ($this->osInfo->isWindows()) { + throw new EnvironmentPreconditionException( + "This test relies on *nix shell and should be skipped in Windows environment." + ); + } + foreach ($this->consumers as $consumer) { + foreach ($this->getConsumerProcessIds($consumer) as $consumerProcessId) { + exec("kill {$consumerProcessId}"); + } + } + foreach ($this->consumers as $consumer) { + if (!$this->getConsumerProcessIds($consumer)) { + exec("{$this->getConsumerStartCommand($consumer, true)} > /dev/null &"); + } + } + + if (file_exists($this->logFilePath)) { + // try to remove before failing the test + unlink($this->logFilePath); + if (file_exists($this->logFilePath)) { + throw new PreconditionFailedException( + "Precondition failed: test log ({$this->logFilePath}) cannot be deleted before test execution." + ); + } + } + } + + /** + * Stop Consumers + */ + public function stopConsumers() + { + foreach ($this->consumers as $consumer) { + foreach ($this->getConsumerProcessIds($consumer) as $consumerProcessId) { + exec("kill {$consumerProcessId}"); + } + } + } + + /** + * @param string $consumer + * @return string[] + */ + private function getConsumerProcessIds($consumer) + { + exec("ps ax | grep -v grep | grep '{$this->getConsumerStartCommand($consumer)}' | awk '{print $1}'", $output); + return $output; + } + + /** + * Get CLI command for starting specified consumer. + * + * @param string $consumer + * @param bool $withEnvVariables + * @return string + */ + private function getConsumerStartCommand($consumer, $withEnvVariables = false) + { + $binDirectory = realpath(TESTS_TEMP_DIR . '/../bin/'); + $magentoCli = $binDirectory . '/magento'; + $consumerStartCommand = "php {$magentoCli} queue:consumers:start -vvv " . $consumer; + if ($this->maxMessages) { + $consumerStartCommand .= " --max-messages={$this->maxMessages}"; + } + if ($withEnvVariables) { + $params = \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams(); + $params['MAGE_DIRS']['base']['path'] = BP; + $params = 'INTEGRATION_TEST_PARAMS="' . urldecode(http_build_query($params)) . '"'; + $consumerStartCommand = $params . ' ' . $consumerStartCommand; + } + return $consumerStartCommand; + } + + /** + * Wait for asynchronous handlers to log data to file. + * + * @param int $expectedLinesCount + * @param string $logFilePath + * @throws PreconditionFailedException + */ + public function waitForAsynchronousResult($expectedLinesCount, $logFilePath) + { + $i = 0; + do { + sleep(1); + $actualCount = file_exists($logFilePath) ? count(file($logFilePath)) : 0; + } while (($expectedLinesCount !== $actualCount) && ($i++ < 180)); + + if (!file_exists($logFilePath)) { + throw new PreconditionFailedException("No asynchronous messages were processed."); + } + } + + /** + * @return PublisherInterface + */ + public function getPublisher() + { + return $this->publisher; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Framework/MessageQueue/UseCase/QueueTestCaseAbstract.php b/dev/tests/integration/testsuite/Magento/Framework/MessageQueue/UseCase/QueueTestCaseAbstract.php index 65f7c5681597e..3a59e79cee45c 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/MessageQueue/UseCase/QueueTestCaseAbstract.php +++ b/dev/tests/integration/testsuite/Magento/Framework/MessageQueue/UseCase/QueueTestCaseAbstract.php @@ -8,6 +8,9 @@ use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\Framework\MessageQueue\PublisherInterface; +use Magento\TestFramework\MessageQueue\PublisherConsumerController; +use Magento\TestFramework\MessageQueue\EnvironmentPreconditionException; +use Magento\TestFramework\MessageQueue\PreconditionFailedException; /** * Base test case for message queue tests. @@ -39,80 +42,36 @@ abstract class QueueTestCaseAbstract extends \PHPUnit\Framework\TestCase */ protected $maxMessages = null; + /** + * @var PublisherConsumerController + */ + private $publisherConsumerController; + protected function setUp() { $this->objectManager = Bootstrap::getObjectManager(); - /** @var \Magento\Framework\OsInfo $osInfo */ - $osInfo = $this->objectManager->get(\Magento\Framework\OsInfo::class); - if ($osInfo->isWindows()) { - $this->markTestSkipped("This test relies on *nix shell and should be skipped in Windows environment."); - } - foreach ($this->consumers as $consumer) { - foreach ($this->getConsumerProcessIds($consumer) as $consumerProcessId) { - exec("kill {$consumerProcessId}"); - } - } - foreach ($this->consumers as $consumer) { - if (!$this->getConsumerProcessIds($consumer)) { - exec("{$this->getConsumerStartCommand($consumer, true)} > /dev/null &"); - } - } - - $this->logFilePath = TESTS_TEMP_DIR . "/MessageQueueTestLog.txt"; - if (file_exists($this->logFilePath)) { - // try to remove before failing the test - unlink($this->logFilePath); - if (file_exists($this->logFilePath)) { - $this->fail( - "Precondition failed: test log ({$this->logFilePath}) cannot be deleted before test execution." - ); - } + $this->publisherConsumerController = $this->objectManager->create(PublisherConsumerController::class, [ + 'consumers' => $this->consumers, + 'logFilePath' => TESTS_TEMP_DIR . "/MessageQueueTestLog.txt", + 'maxMessages' => $this->maxMessages, + 'appInitParams' => \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams() + ]); + + try { + $this->publisherConsumerController->initialize(); + } catch (EnvironmentPreconditionException $e) { + $this->markTestSkipped($e->getMessage()); + } catch (PreconditionFailedException $e) { + $this->fail( + $e->getMessage() + ); } - - $this->publisher = $this->objectManager->get(PublisherInterface::class); + $this->publisher = $this->publisherConsumerController->getPublisher(); } protected function tearDown() { - foreach ($this->consumers as $consumer) { - foreach ($this->getConsumerProcessIds($consumer) as $consumerProcessId) { - exec("kill {$consumerProcessId}"); - } - } - } - - /** - * @param string $consumer - * @return string[] - */ - protected function getConsumerProcessIds($consumer) - { - exec("ps ax | grep -v grep | grep '{$this->getConsumerStartCommand($consumer)}' | awk '{print $1}'", $output); - return $output; - } - - /** - * Get CLI command for starting specified consumer. - * - * @param string $consumer - * @param bool $withEnvVariables - * @return string - */ - protected function getConsumerStartCommand($consumer, $withEnvVariables = false) - { - $binDirectory = realpath(TESTS_TEMP_DIR . '/../bin/'); - $magentoCli = $binDirectory . '/magento'; - $consumerStartCommand = "php {$magentoCli} queue:consumers:start -vvv " . $consumer; - if ($this->maxMessages) { - $consumerStartCommand .= " --max-messages={$this->maxMessages}"; - } - if ($withEnvVariables) { - $params = \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams(); - $params['MAGE_DIRS']['base']['path'] = BP; - $params = 'INTEGRATION_TEST_PARAMS="' . urldecode(http_build_query($params)) . '"'; - $consumerStartCommand = $params . ' ' . $consumerStartCommand; - } - return $consumerStartCommand; + $this->publisherConsumerController->stopConsumers(); } /** @@ -123,14 +82,10 @@ protected function getConsumerStartCommand($consumer, $withEnvVariables = false) */ protected function waitForAsynchronousResult($expectedLinesCount, $logFilePath) { - $i = 0; - do { - sleep(1); - $actualCount = file_exists($logFilePath) ? count(file($logFilePath)) : 0; - } while (($expectedLinesCount !== $actualCount) && ($i++ < 180)); - - if (!file_exists($logFilePath)) { - $this->fail("No asynchronous messages were processed."); + try { + $this->publisherConsumerController->waitForAsynchronousResult($expectedLinesCount, $logFilePath); + } catch (PreconditionFailedException $e) { + $this->fail($e->getMessage()); } } diff --git a/app/code/Magento/WebapiAsync/Test/ApiFunctional/BulkScheduleTest.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/BulkScheduleTest.php similarity index 99% rename from app/code/Magento/WebapiAsync/Test/ApiFunctional/BulkScheduleTest.php rename to dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/BulkScheduleTest.php index 29f0b299ce128..277d1f674f42c 100644 --- a/app/code/Magento/WebapiAsync/Test/ApiFunctional/BulkScheduleTest.php +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/BulkScheduleTest.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\WebapiAsync\Test\ApiFunctional; +namespace Magento\WebapiAsync\Model\MessageQueue; use Magento\Catalog\Api\Data\ProductInterface; use Magento\TestFramework\TestCase\WebapiAbstract; @@ -99,7 +99,7 @@ protected function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); $this->shellMock = $this->getMockBuilder(ShellInterface::class) - ->getMockForAbstractClass(); + ->getMockForAbstractClass(); $this->pid = $this->objectManager->get(PidConsumerManager::class); $this->consumerConfig = $this->objectManager->get(ConsumerConfigInterface::class); $this->reader = $this->objectManager->get(FileReader::class); diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/WebapiAsyncBaseTestCase.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/WebapiAsyncBaseTestCase.php new file mode 100644 index 0000000000000..089d663e181c1 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/WebapiAsyncBaseTestCase.php @@ -0,0 +1,105 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync; + +use Magento\TestFramework\TestCase\WebapiAbstract; +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Framework\MessageQueue\PublisherInterface; +use Magento\TestFramework\MessageQueue\PublisherConsumerController; +use Magento\TestFramework\MessageQueue\EnvironmentPreconditionException; +use Magento\TestFramework\MessageQueue\PreconditionFailedException; + +class WebApiAsyncBaseTestCase extends WebapiAbstract +{ + /** + * @var string[] + */ + protected $consumers = []; + + /** + * @var ObjectManagerInterface + */ + protected $objectManager; + + /** + * @var PublisherInterface + */ + protected $publisher; + + /** + * @var string + */ + protected $logFilePath; + + /** + * @var int|null + */ + protected $maxMessages = null; + + /** + * @var PublisherConsumerController + */ + private $publisherConsumerController; + + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->publisherConsumerController = $this->objectManager->get(PublisherConsumerController::class, [ + 'consumers' => $this->consumers, + 'logFilePath' => TESTS_TEMP_DIR . "/MessageQueueTestLog.txt", + 'maxMessages' => $this->maxMessages, + 'appInitParams' => \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams() + ]); + + try { + $this->publisherConsumerController->initialize(); + } catch (EnvironmentPreconditionException $e) { + $this->markTestSkipped($e->getMessage()); + } catch (PreconditionFailedException $e) { + $this->fail( + $e->getMessage() + ); + } + } + + protected function tearDown() + { + $this->publisherConsumerController->stopConsumers(); + parent::tearDown(); + } + + /** + * Wait for asynchronous handlers to log data to file. + * + * @param int $expectedLinesCount + * @param string $logFilePath + */ + protected function waitForAsynchronousResult($expectedLinesCount, $logFilePath) + { + try { + $this->publisherConsumerController->waitForAsynchronousResult($expectedLinesCount, $logFilePath); + } catch (PreconditionFailedException $e) { + $this->fail($e->getMessage()); + } + } + + /** + * Workaround for https://bugs.php.net/bug.php?id=72286 + */ + public static function tearDownAfterClass() + { + if (version_compare(phpversion(), '7') == -1) { + $closeConnection = new \ReflectionMethod(\Magento\Amqp\Model\Config::class, 'closeConnection'); + $closeConnection->setAccessible(true); + + $config = Bootstrap::getObjectManager()->get(\Magento\Amqp\Model\Config::class); + $closeConnection->invoke($config); + } + parent::tearDownAfterClass(); + } +} \ No newline at end of file From 623bc6a565c977ed8515c5713eac9bb04e0bd219 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <okopylova@magento.com> Date: Thu, 22 Mar 2018 21:51:38 -0500 Subject: [PATCH 168/668] MAGETWO-89395: Encryption support - fixed static test --- .../Magento/Framework/Encryption/Test/Unit/CryptTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php b/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php index de5a669632337..562f01abeefd1 100644 --- a/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php +++ b/lib/internal/Magento/Framework/Encryption/Test/Unit/CryptTest.php @@ -93,8 +93,9 @@ public function getConstructorExceptionData() $tooShortInitVector = str_repeat('-', $this->_getInitVectorSize($cipher, $mode) - 1); $tooLongInitVector = str_repeat('-', $this->_getInitVectorSize($cipher, $mode) + 1); $result['tooLongKey-' . $cipher . '-' . $mode . '-false'] = [$tooLongKey, $cipher, $mode, false]; - $result['key-' . $cipher . '-' . $mode . '-tooShortInitVector'] = [$this->_key, $cipher, $mode, $tooShortInitVector]; - $result['key-' . $cipher . '-' . $mode . '-tooLongInitVector'] = [$this->_key, $cipher, $mode, $tooLongInitVector]; + $keyPrefix = 'key-' . $cipher . '-' . $mode; + $result[$keyPrefix . '-tooShortInitVector'] = [$this->_key, $cipher, $mode, $tooShortInitVector]; + $result[$keyPrefix . '-tooLongInitVector'] = [$this->_key, $cipher, $mode, $tooLongInitVector]; } } return $result; From b582ef6e1b804062ffd834ce0be46d1cf5b4b94d Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Thu, 22 Mar 2018 22:13:30 -0500 Subject: [PATCH 169/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - changed Swagger path --- .../Controller/Rest/AsynchronousSchemaRequestProcessor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessor.php b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessor.php index 1da14ac9c6b20..3f1219575b96e 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessor.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessor.php @@ -66,7 +66,7 @@ public function process(\Magento\Framework\Webapi\Rest\Request $request) */ public function canProcess(\Magento\Framework\Webapi\Rest\Request $request) { - if (preg_match(self::PROCESSOR_PATH, ltrim($request->getPathInfo(), '/')) === 0) { + if (strpos(ltrim($request->getPathInfo(), '/'), self::PROCESSOR_PATH) === 0) { return true; } return false; From 9fdca343c2d0ae46eea5fc6033ec3cc7d064fb30 Mon Sep 17 00:00:00 2001 From: Carey Sizer <carey@balanceinternet.com.au> Date: Thu, 22 Feb 2018 08:02:26 +1300 Subject: [PATCH 170/668] Implemented ability to expose arbitrary Swagger schema types - Extracted default rest implementation to SwaggerWebapi module --- .../Api/Block/SchemaTypesInterface.php | 30 +++++ .../Swagger/Api/SchemaTypeInterface.php | 29 +++++ app/code/Magento/Swagger/Block/Index.php | 25 ++++- .../Magento/Swagger/Block/SchemaTypes.php | 59 ++++++++++ .../Swagger/Controller/Index/Index.php | 5 +- .../Swagger/Test/Unit/Block/IndexTest.php | 103 ++++++++++++++++++ .../Test/Unit/Block/SchemaTypesTest.php | 62 +++++++++++ app/code/Magento/Swagger/etc/frontend/di.xml | 10 ++ app/code/Magento/Swagger/etc/module.xml | 6 +- .../frontend/layout/swagger_index_index.xml | 6 +- app/code/Magento/SwaggerWebapi/LICENSE.txt | 48 ++++++++ .../Magento/SwaggerWebapi/LICENSE_AFL.txt | 48 ++++++++ .../SwaggerWebapi/Model/SchemaType/Rest.php | 48 ++++++++ app/code/Magento/SwaggerWebapi/README.md | 1 + .../Test/Unit/Model/SchemaType/RestTest.php | 64 +++++++++++ app/code/Magento/SwaggerWebapi/composer.json | 26 +++++ .../Magento/SwaggerWebapi/etc/frontend/di.xml | 23 ++++ app/code/Magento/SwaggerWebapi/etc/module.xml | 14 +++ .../Magento/SwaggerWebapi/registration.php | 9 ++ composer.json | 3 +- .../SwaggerWebapi/Block/Swagger/IndexTest.php | 57 ++++++++++ .../Block/Swagger/SchemaTypesTest.php | 46 ++++++++ 22 files changed, 716 insertions(+), 6 deletions(-) create mode 100644 app/code/Magento/Swagger/Api/Block/SchemaTypesInterface.php create mode 100644 app/code/Magento/Swagger/Api/SchemaTypeInterface.php create mode 100644 app/code/Magento/Swagger/Block/SchemaTypes.php create mode 100644 app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php create mode 100644 app/code/Magento/Swagger/Test/Unit/Block/SchemaTypesTest.php create mode 100644 app/code/Magento/Swagger/etc/frontend/di.xml create mode 100644 app/code/Magento/SwaggerWebapi/LICENSE.txt create mode 100644 app/code/Magento/SwaggerWebapi/LICENSE_AFL.txt create mode 100644 app/code/Magento/SwaggerWebapi/Model/SchemaType/Rest.php create mode 100644 app/code/Magento/SwaggerWebapi/README.md create mode 100644 app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php create mode 100644 app/code/Magento/SwaggerWebapi/composer.json create mode 100644 app/code/Magento/SwaggerWebapi/etc/frontend/di.xml create mode 100644 app/code/Magento/SwaggerWebapi/etc/module.xml create mode 100644 app/code/Magento/SwaggerWebapi/registration.php create mode 100644 dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/IndexTest.php create mode 100644 dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/SchemaTypesTest.php diff --git a/app/code/Magento/Swagger/Api/Block/SchemaTypesInterface.php b/app/code/Magento/Swagger/Api/Block/SchemaTypesInterface.php new file mode 100644 index 0000000000000..21170ca1a6c85 --- /dev/null +++ b/app/code/Magento/Swagger/Api/Block/SchemaTypesInterface.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Swagger\Api\Block; + +use Magento\Swagger\Api\SchemaTypeInterface; + +/** + * Swagger Schema Types. + * + * @api + */ +interface SchemaTypesInterface +{ + /** + * Retrieve the available types of Swagger schema. + * + * @return SchemaTypeInterface[] + */ + public function getTypes(); + + /** + * Retrieve the default schema type for Swagger. + * + * @return SchemaTypeInterface + */ + public function getDefault(); +} diff --git a/app/code/Magento/Swagger/Api/SchemaTypeInterface.php b/app/code/Magento/Swagger/Api/SchemaTypeInterface.php new file mode 100644 index 0000000000000..868e64d276ad3 --- /dev/null +++ b/app/code/Magento/Swagger/Api/SchemaTypeInterface.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Swagger\Api; + +/** + * Swagger Schema Type. + * + * @api + */ +interface SchemaTypeInterface +{ + /** + * Retrieve the available types of Swagger schema. + * + * @return string + */ + public function getCode(); + + /** + * Get the URL path for the Swagger schema. + * + * @param string|null $store + * @return string + */ + public function getSchemaUrlPath($store = null); +} diff --git a/app/code/Magento/Swagger/Block/Index.php b/app/code/Magento/Swagger/Block/Index.php index 91b67fe4e7f44..6894e625325e6 100644 --- a/app/code/Magento/Swagger/Block/Index.php +++ b/app/code/Magento/Swagger/Block/Index.php @@ -6,11 +6,14 @@ namespace Magento\Swagger\Block; use Magento\Framework\View\Element\Template; +use Magento\Swagger\Api\SchemaTypeInterface; /** * Block for swagger index page * * @api + * + * @method \Magento\Swagger\Api\Block\SchemaTypesInterface getSchemaTypes() */ class Index extends Template { @@ -22,11 +25,31 @@ private function getParamStore() return $this->getRequest()->getParam('store') ?: 'all'; } + /** + * @return SchemaTypeInterface + */ + private function getParamSchemaType() + { + $schemaTypeCode = $this->getRequest()->getParam( + 'type', + $this->getSchemaTypes()->getDefault()->getCode() + ); + + foreach ($this->getSchemaTypes()->getTypes() as $schemaType) { + if ($schemaTypeCode === $schemaType->getCode()) { + return $schemaType; + } + } + + return $this->getSchemaTypes()->getDefault(); + } + /** * @return string */ public function getSchemaUrl() { - return rtrim($this->getBaseUrl(), '/') . '/rest/' . $this->getParamStore() . '/schema?services=all'; + return rtrim($this->getBaseUrl(), '/') . + $this->getParamSchemaType()->getSchemaUrlPath($this->getParamStore()); } } diff --git a/app/code/Magento/Swagger/Block/SchemaTypes.php b/app/code/Magento/Swagger/Block/SchemaTypes.php new file mode 100644 index 0000000000000..f9d9cd795119c --- /dev/null +++ b/app/code/Magento/Swagger/Block/SchemaTypes.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Swagger\Block; + +use Magento\Framework\View\Element\Block\ArgumentInterface; +use Magento\Swagger\Api\Block\SchemaTypesInterface; +use Magento\Swagger\Api\SchemaTypeInterface; + +/** + * Schema Type Options. + */ +class SchemaTypes implements SchemaTypesInterface, ArgumentInterface +{ + /** + * @var SchemaTypeInterface + */ + private $default; + /** + * @var SchemaTypeInterface[]|null + */ + private $types; + + /** + * SchemaTypes constructor. + * + * @param array|SchemaTypeInterface[] $types + */ + public function __construct( + array $types = [] + ) { + $this->types = $types; + if (count($this->types) > 0) { + $this->default = array_values($this->types)[0]; + } + } + + /** + * Retrieve the available types of Swagger schema. + * + * @return SchemaTypeInterface[] + */ + public function getTypes() + { + return $this->types; + } + + /** + * Retrieve the default schema type for Swagger. + * + * @return SchemaTypeInterface|null + */ + public function getDefault() + { + return $this->default; + } +} diff --git a/app/code/Magento/Swagger/Controller/Index/Index.php b/app/code/Magento/Swagger/Controller/Index/Index.php index e10a9235c4181..147466642f354 100644 --- a/app/code/Magento/Swagger/Controller/Index/Index.php +++ b/app/code/Magento/Swagger/Controller/Index/Index.php @@ -7,6 +7,7 @@ /** * Class Index + * * @package Magento\Swagger\Controller\Index */ class Index extends \Magento\Framework\App\Action\Action @@ -22,8 +23,8 @@ class Index extends \Magento\Framework\App\Action\Action private $pageFactory; /** - * @param \Magento\Framework\App\Action\Context $context - * @param \Magento\Framework\View\Page\Config $pageConfig + * @param \Magento\Framework\App\Action\Context $context + * @param \Magento\Framework\View\Page\Config $pageConfig * @param \Magento\Framework\View\Result\PageFactory $pageFactory */ public function __construct( diff --git a/app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php b/app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php new file mode 100644 index 0000000000000..9746cfac73cd0 --- /dev/null +++ b/app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php @@ -0,0 +1,103 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Swagger\Test\Unit\Block; + +use Magento\Framework\App\RequestInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\View\Element\Template\Context; +use Magento\Swagger\Api\SchemaTypeInterface; +use Magento\Swagger\Block\Index; +use Magento\Swagger\Block\SchemaTypes; + +class IndexTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var SchemaTypeInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $schemaTypeMock; + + /** + * @var RequestInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $requestMock; + + /** + * @var Index + */ + private $index; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->requestMock = $this->getMockBuilder(RequestInterface::class)->getMock(); + $this->schemaTypeMock = $this->getMockBuilder(SchemaTypeInterface::class)->getMock(); + + $this->index = (new ObjectManager($this))->getObject( + Index::class, + [ + 'context' => (new ObjectManager($this))->getObject( + Context::class, + [ + 'request' => $this->requestMock, + ] + ), + 'data' => [ + 'schema_types' => (new ObjectManager($this))->getObject( + SchemaTypes::class, + [ + 'types' => [$this->schemaTypeMock] + ] + ) + ] + ] + ); + } + + /** + * Test that the passed URL parameter is used when it is a valid schema type. + * + * @covers \Magento\Swagger\Block\Index::getSchemaUrl() + */ + public function testGetSchemaUrlValidType() + { + $this->requestMock->expects($this->atLeastOnce()) + ->method('getParam') + ->willReturn('test'); + + $this->schemaTypeMock->expects($this->any()) + ->method('getCode')->willReturn('test'); + + $this->schemaTypeMock->expects($this->once()) + ->method('getSchemaUrlPath') + ->willReturn('/test'); + + $this->assertEquals('/test', $this->index->getSchemaUrl()); + } + + /** + * Test that the passed URL parameter is not used when it is not a valid schema type. + * + * @covers \Magento\Swagger\Block\Index::getSchemaUrl() + */ + public function testGetSchemaUrlInvalidType() + { + $this->requestMock->expects($this->atLeastOnce()) + ->method('getParam') + ->willReturn('invalid'); + + $this->schemaTypeMock->expects($this->any()) + ->method('getCode')->willReturn('test'); + + $this->schemaTypeMock->expects($this->once()) + ->method('getSchemaUrlPath') + ->willReturn('/test'); + + $this->assertEquals('/test', $this->index->getSchemaUrl()); + } +} diff --git a/app/code/Magento/Swagger/Test/Unit/Block/SchemaTypesTest.php b/app/code/Magento/Swagger/Test/Unit/Block/SchemaTypesTest.php new file mode 100644 index 0000000000000..5ccbd777d17f6 --- /dev/null +++ b/app/code/Magento/Swagger/Test/Unit/Block/SchemaTypesTest.php @@ -0,0 +1,62 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Store\Test\Unit\Block; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Swagger\Api\SchemaTypeInterface; +use Magento\Swagger\Block\SchemaTypes; + +class SchemaTypesTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var SchemaTypeInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $defaultType; + + /** + * @var SchemaTypes + */ + private $schemaTypes; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->defaultType = $this->getMockBuilder(SchemaTypeInterface::class) + ->getMock(); + + $this->schemaTypes = (new ObjectManager($this))->getObject( + SchemaTypes::class, + [ + 'types' => [ + $this->defaultType, + $this->getMockBuilder(SchemaTypeInterface::class)->getMock() + ] + ] + ); + } + + /** + * @covers \Magento\Swagger\Block\SchemaTypes::getTypes() + */ + public function testGetTypes() + { + $this->assertCount(2, $this->schemaTypes->getTypes()); + $this->assertContains($this->defaultType, $this->schemaTypes->getTypes()); + } + + /** + * Test that the first type supplied to SchemaTypes is the default + * + * @covers \Magento\Swagger\Block\SchemaTypes::getDefault() + */ + public function testGetDefaultType() + { + $this->assertEquals($this->defaultType, $this->schemaTypes->getDefault()); + } +} diff --git a/app/code/Magento/Swagger/etc/frontend/di.xml b/app/code/Magento/Swagger/etc/frontend/di.xml new file mode 100644 index 0000000000000..28ea4107d5453 --- /dev/null +++ b/app/code/Magento/Swagger/etc/frontend/di.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <preference for="Magento\Swagger\Api\Block\SchemaTypesInterface" type="Magento\Swagger\Block\SchemaTypes"/> +</config> \ No newline at end of file diff --git a/app/code/Magento/Swagger/etc/module.xml b/app/code/Magento/Swagger/etc/module.xml index fce24b61b4f86..9a136e619e12b 100644 --- a/app/code/Magento/Swagger/etc/module.xml +++ b/app/code/Magento/Swagger/etc/module.xml @@ -6,5 +6,9 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_Swagger" /> + <module name="Magento_Swagger"> + <sequence> + <module name="Magento_SwaggerWebapi" /> + </sequence> + </module> </config> diff --git a/app/code/Magento/Swagger/view/frontend/layout/swagger_index_index.xml b/app/code/Magento/Swagger/view/frontend/layout/swagger_index_index.xml index 458102c38bf6f..bd6fcb5facf8a 100644 --- a/app/code/Magento/Swagger/view/frontend/layout/swagger_index_index.xml +++ b/app/code/Magento/Swagger/view/frontend/layout/swagger_index_index.xml @@ -45,7 +45,11 @@ <referenceContainer name="page.wrapper" remove="true"/> <referenceBlock name="requirejs-config" remove="true"/> <referenceContainer name="root"> - <block name="swaggerUiContent" class="Magento\Swagger\Block\Index" template="Magento_Swagger::swagger-ui/index.phtml"/> + <block name="swaggerUiContent" class="Magento\Swagger\Block\Index" template="Magento_Swagger::swagger-ui/index.phtml"> + <arguments> + <argument name="schema_types" xsi:type="object">Magento\Swagger\Api\Block\SchemaTypesInterface</argument> + </arguments> + </block> </referenceContainer> </body> </page> diff --git a/app/code/Magento/SwaggerWebapi/LICENSE.txt b/app/code/Magento/SwaggerWebapi/LICENSE.txt new file mode 100644 index 0000000000000..49525fd99da9c --- /dev/null +++ b/app/code/Magento/SwaggerWebapi/LICENSE.txt @@ -0,0 +1,48 @@ + +Open Software License ("OSL") v. 3.0 + +This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: + +Licensed under the Open Software License version 3.0 + + 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: + + 1. to reproduce the Original Work in copies, either alone or as part of a collective work; + + 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; + + 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License; + + 4. to perform the Original Work publicly; and + + 5. to display the Original Work publicly. + + 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. + + 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. + + 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. + + 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). + + 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. + + 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. + + 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. + + 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including 'fair use' or 'fair dealing'). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). + + 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. + + 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. + + 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. + + 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. + + 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. + + 16. Modification of This License. This License is Copyright (C) 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. \ No newline at end of file diff --git a/app/code/Magento/SwaggerWebapi/LICENSE_AFL.txt b/app/code/Magento/SwaggerWebapi/LICENSE_AFL.txt new file mode 100644 index 0000000000000..f39d641b18a19 --- /dev/null +++ b/app/code/Magento/SwaggerWebapi/LICENSE_AFL.txt @@ -0,0 +1,48 @@ + +Academic Free License ("AFL") v. 3.0 + +This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: + +Licensed under the Academic Free License version 3.0 + + 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: + + 1. to reproduce the Original Work in copies, either alone or as part of a collective work; + + 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; + + 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor's reserved rights and remedies, in this Academic Free License; + + 4. to perform the Original Work publicly; and + + 5. to display the Original Work publicly. + + 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. + + 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. + + 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. + + 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). + + 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. + + 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. + + 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. + + 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). + + 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. + + 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. + + 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. + + 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. + + 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. + + 16. Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. diff --git a/app/code/Magento/SwaggerWebapi/Model/SchemaType/Rest.php b/app/code/Magento/SwaggerWebapi/Model/SchemaType/Rest.php new file mode 100644 index 0000000000000..248a56bd09ed6 --- /dev/null +++ b/app/code/Magento/SwaggerWebapi/Model/SchemaType/Rest.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SwaggerWebapi\Model\SchemaType; + +use Magento\Swagger\Api\SchemaTypeInterface; + +/** + * Rest swagger schema type. + */ +class Rest implements SchemaTypeInterface +{ + /** + * @var string + */ + private $code; + + /** + * Rest constructor. + * + * @param string $code + */ + public function __construct(string $code) + { + $this->code = $code; + } + + /** + * @return string + */ + public function getCode() + { + return $this->code; + } + + /** + * @param string|null $store + * @return string + */ + public function getSchemaUrlPath($store = null) + { + $store = $store ?? 'all'; + + return '/' . $this->code . '/' . $store . '/schema?services=all'; + } +} diff --git a/app/code/Magento/SwaggerWebapi/README.md b/app/code/Magento/SwaggerWebapi/README.md new file mode 100644 index 0000000000000..3529848949d77 --- /dev/null +++ b/app/code/Magento/SwaggerWebapi/README.md @@ -0,0 +1 @@ +The Magento_SwaggerWebapi module provides the implementation of the REST Webapi module with Magento_Swagger. \ No newline at end of file diff --git a/app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php b/app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php new file mode 100644 index 0000000000000..465870f331807 --- /dev/null +++ b/app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\SwaggerWebapi\Test\Unit\Model\SchemaType; + +use Magento\Swagger\Api\SchemaTypeInterface; +use Magento\SwaggerWebapi\Model\SchemaType\Rest; + +class RestTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var SchemaTypeInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $rest; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->rest = new Rest('rest'); + } + + /** + * @covers \Magento\SwaggerWebapi\Model\SchemaType\Rest::getSchemaUrlPathProvider + * + * @param $expected + * @param null|string $store + * + * @dataProvider getSchemaUrlPathProvider + */ + public function testGetSchemaUrlPath($expected, $store = null) + { + $this->assertEquals($expected, $this->rest->getSchemaUrlPath($store)); + } + + /** + * @covers \Magento\SwaggerWebapi\Model\SchemaType\Rest::getCode() + */ + public function testGetCode() + { + $this->assertEquals('rest', $this->rest->getCode()); + } + + /** + * @return array + */ + public function getSchemaUrlPathProvider() + { + return [ + [ + '/rest/all/schema?services=all', + null + ], + [ + '/rest/test/schema?services=all', + 'test' + ] + ]; + } +} diff --git a/app/code/Magento/SwaggerWebapi/composer.json b/app/code/Magento/SwaggerWebapi/composer.json new file mode 100644 index 0000000000000..6650aad914bd5 --- /dev/null +++ b/app/code/Magento/SwaggerWebapi/composer.json @@ -0,0 +1,26 @@ +{ + "name": "magento/module-swagger-webapi", + "description": "N/A", + "config": { + "sort-packages": true + }, + "require": { + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "magento/framework": "100.3.*", + "magento/module-swagger": "100.3.*" + }, + "type": "magento2-module", + "version": "100.3.0-dev", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Swagger\\": "" + } + } +} diff --git a/app/code/Magento/SwaggerWebapi/etc/frontend/di.xml b/app/code/Magento/SwaggerWebapi/etc/frontend/di.xml new file mode 100644 index 0000000000000..5a487ddb41f68 --- /dev/null +++ b/app/code/Magento/SwaggerWebapi/etc/frontend/di.xml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <type name="Magento\SwaggerWebapi\Model\SchemaType\Rest"> + <arguments> + <!-- @todo: implement constant once merged with other bulk-api changes --> + <argument name="code" xsi:type="string">rest</argument> + </arguments> + </type> + + <type name="Magento\Swagger\Block\SchemaTypes"> + <arguments> + <argument name="types" xsi:type="array"> + <item name="rest" xsi:type="object">Magento\SwaggerWebapi\Model\SchemaType\Rest</item> + </argument> + </arguments> + </type> +</config> \ No newline at end of file diff --git a/app/code/Magento/SwaggerWebapi/etc/module.xml b/app/code/Magento/SwaggerWebapi/etc/module.xml new file mode 100644 index 0000000000000..1ab25b58ae8f9 --- /dev/null +++ b/app/code/Magento/SwaggerWebapi/etc/module.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> + <module name="Magento_SwaggerWebapi" setup_version="0.0.1"> + <sequence> + <module name="Magento_Webapi" /> + </sequence> + </module> +</config> diff --git a/app/code/Magento/SwaggerWebapi/registration.php b/app/code/Magento/SwaggerWebapi/registration.php new file mode 100644 index 0000000000000..2c76d70a6e1ad --- /dev/null +++ b/app/code/Magento/SwaggerWebapi/registration.php @@ -0,0 +1,9 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use \Magento\Framework\Component\ComponentRegistrar; + +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_SwaggerWebapi', __DIR__); diff --git a/composer.json b/composer.json index 661468f438bc6..fe3fc5be1f506 100644 --- a/composer.json +++ b/composer.json @@ -205,6 +205,7 @@ "magento/module-sitemap": "100.3.0-dev", "magento/module-store": "100.3.0-dev", "magento/module-swagger": "100.3.0-dev", + "magento/module-swagger-webapi": "100.3.0-dev", "magento/module-swatches": "100.3.0-dev", "magento/module-swatches-layered-navigation": "100.3.0-dev", "magento/module-tax": "100.3.0-dev", @@ -297,4 +298,4 @@ } }, "prefer-stable": true -} +} \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/IndexTest.php b/dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/IndexTest.php new file mode 100644 index 0000000000000..5dd8aed539c8a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/IndexTest.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SwaggerWebapi\Block\Swagger; + +/** + * @magentoAppArea frontend + */ +class IndexTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Swagger\Block\Index + */ + private $block; + + protected function setUp() + { + \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\App\State::class) + ->setAreaCode('frontend'); + + $this->block = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Framework\View\LayoutInterface::class + )->createBlock( + \Magento\Swagger\Block\Index::class, + '', + [ + 'data' => [ + 'schema_types' => \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Swagger\Api\Block\SchemaTypesInterface::class + ) + ] + ] + ); + } + + /** + * Test that the Swagger UI outputs rest as the default when there is no type parameter supplied via URL. + */ + public function testDefaultSchemaUrlOutput() + { + $this->assertStringEndsWith('/rest/all/schema?services=all', $this->block->getSchemaUrl()); + } + + /** + * Test that Swagger UI outputs the supplied store code when it is specified. + */ + public function testSchemaUrlOutputWithStore() + { + $this->block->getRequest()->setParams([ + 'store' => 'custom', + ]); + + $this->assertStringEndsWith('/rest/custom/schema?services=all', $this->block->getSchemaUrl()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/SchemaTypesTest.php b/dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/SchemaTypesTest.php new file mode 100644 index 0000000000000..73307fdc1f486 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/SchemaTypesTest.php @@ -0,0 +1,46 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SwaggerWebapi\Block\Swagger; + +use Magento\Swagger\Api\Block\SchemaTypesInterface; + +/** + * @magentoAppArea frontend + */ +class SchemaTypesTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Swagger\Block\SchemaTypes + */ + private $schemaTypes; + + protected function setUp() + { + \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\App\State::class) + ->setAreaCode('frontend'); + + $this->schemaTypes = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + SchemaTypesInterface::class + ); + } + + /** + * Test that the Swagger SchemaTypes contains the type added by SwaggerWebapi. + */ + public function testContainsSchemaType() + { + $schemaExists = function () { + foreach ($this->schemaTypes->getTypes() as $schemaType) { + if ($schemaType->getCode() === 'rest') { + return true; + } + } + return false; + }; + + $this->assertTrue($schemaExists()); + } +} From bca27cbc5ffa408cfff33dfe7ff00bfb4fbbc14c Mon Sep 17 00:00:00 2001 From: Carey Sizer <carey@balanceinternet.com.au> Date: Tue, 6 Mar 2018 18:08:45 +1300 Subject: [PATCH 171/668] Changes to Swagger & Swaggerwebapi - Renamed Magento\Swagger\Block\Index::getParamSchemaType() to Magento\Swagger\Block\Index::getSchemaType() - Changed injection of SchemaTypes to a native PHP array, removed SchemaTypesInterface argument to swagger block - Changed composer version - Fixed composer namespace in SwaggerWebapi - Added requires to composer for both modules (they will require this in the future due to a constant required from Webapi & WebapiAsync) - Changed setup_version to 2.0.0 --- .../Api/Block/SchemaTypesInterface.php | 30 --------- .../Api/{ => Data}/SchemaTypeInterface.php | 6 +- app/code/Magento/Swagger/Block/Index.php | 35 +++++++---- .../Magento/Swagger/Block/SchemaTypes.php | 59 ------------------ .../Swagger/Test/Unit/Block/IndexTest.php | 18 +++--- .../Test/Unit/Block/SchemaTypesTest.php | 62 ------------------- app/code/Magento/Swagger/composer.json | 7 ++- .../frontend/layout/swagger_index_index.xml | 7 +-- .../SwaggerWebapi/Model/SchemaType/Rest.php | 2 +- .../Test/Unit/Model/SchemaType/RestTest.php | 2 +- .../Magento/SwaggerWebapi/etc/frontend/di.xml | 8 --- app/code/Magento/SwaggerWebapi/etc/module.xml | 2 +- .../frontend/layout/swagger_index_index.xml | 19 ++++++ .../SwaggerWebapi/Block/Swagger/IndexTest.php | 9 ++- .../Block/Swagger/SchemaTypesTest.php | 46 -------------- 15 files changed, 67 insertions(+), 245 deletions(-) delete mode 100644 app/code/Magento/Swagger/Api/Block/SchemaTypesInterface.php rename app/code/Magento/Swagger/Api/{ => Data}/SchemaTypeInterface.php (75%) delete mode 100644 app/code/Magento/Swagger/Block/SchemaTypes.php delete mode 100644 app/code/Magento/Swagger/Test/Unit/Block/SchemaTypesTest.php create mode 100644 app/code/Magento/SwaggerWebapi/view/frontend/layout/swagger_index_index.xml delete mode 100644 dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/SchemaTypesTest.php diff --git a/app/code/Magento/Swagger/Api/Block/SchemaTypesInterface.php b/app/code/Magento/Swagger/Api/Block/SchemaTypesInterface.php deleted file mode 100644 index 21170ca1a6c85..0000000000000 --- a/app/code/Magento/Swagger/Api/Block/SchemaTypesInterface.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Swagger\Api\Block; - -use Magento\Swagger\Api\SchemaTypeInterface; - -/** - * Swagger Schema Types. - * - * @api - */ -interface SchemaTypesInterface -{ - /** - * Retrieve the available types of Swagger schema. - * - * @return SchemaTypeInterface[] - */ - public function getTypes(); - - /** - * Retrieve the default schema type for Swagger. - * - * @return SchemaTypeInterface - */ - public function getDefault(); -} diff --git a/app/code/Magento/Swagger/Api/SchemaTypeInterface.php b/app/code/Magento/Swagger/Api/Data/SchemaTypeInterface.php similarity index 75% rename from app/code/Magento/Swagger/Api/SchemaTypeInterface.php rename to app/code/Magento/Swagger/Api/Data/SchemaTypeInterface.php index 868e64d276ad3..076581c1385e2 100644 --- a/app/code/Magento/Swagger/Api/SchemaTypeInterface.php +++ b/app/code/Magento/Swagger/Api/Data/SchemaTypeInterface.php @@ -3,14 +3,16 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Swagger\Api; +namespace Magento\Swagger\Api\Data; + +use Magento\Framework\View\Element\Block\ArgumentInterface; /** * Swagger Schema Type. * * @api */ -interface SchemaTypeInterface +interface SchemaTypeInterface extends ArgumentInterface { /** * Retrieve the available types of Swagger schema. diff --git a/app/code/Magento/Swagger/Block/Index.php b/app/code/Magento/Swagger/Block/Index.php index 6894e625325e6..549495190ef34 100644 --- a/app/code/Magento/Swagger/Block/Index.php +++ b/app/code/Magento/Swagger/Block/Index.php @@ -5,15 +5,18 @@ */ namespace Magento\Swagger\Block; +use Magento\Framework\Phrase; use Magento\Framework\View\Element\Template; -use Magento\Swagger\Api\SchemaTypeInterface; +use Magento\Swagger\Api\Data\SchemaTypeInterface; /** * Block for swagger index page * * @api * - * @method \Magento\Swagger\Api\Block\SchemaTypesInterface getSchemaTypes() + * @method SchemaTypeInterface[] getSchemaTypes() + * @method bool hasSchemaTypes() + * @method string getDefaultSchemaTypeCode() */ class Index extends Template { @@ -26,30 +29,38 @@ private function getParamStore() } /** - * @return SchemaTypeInterface + * @return SchemaTypeInterface|null */ - private function getParamSchemaType() + private function getSchemaType() { + if (!$this->hasSchemaTypes()) { + return null; + } + $schemaTypeCode = $this->getRequest()->getParam( 'type', - $this->getSchemaTypes()->getDefault()->getCode() + $this->getDefaultSchemaTypeCode() ); - foreach ($this->getSchemaTypes()->getTypes() as $schemaType) { - if ($schemaTypeCode === $schemaType->getCode()) { - return $schemaType; - } + if (!array_key_exists($schemaTypeCode, $this->getSchemaTypes())) { + throw new \UnexpectedValueException( + new Phrase('Unknown schema type supplied') + ); } - return $this->getSchemaTypes()->getDefault(); + return $this->getSchemaTypes()[$schemaTypeCode]; } /** - * @return string + * @return string|null */ public function getSchemaUrl() { + if ($this->getSchemaType() === null) { + return null; + } + return rtrim($this->getBaseUrl(), '/') . - $this->getParamSchemaType()->getSchemaUrlPath($this->getParamStore()); + $this->getSchemaType()->getSchemaUrlPath($this->getParamStore()); } } diff --git a/app/code/Magento/Swagger/Block/SchemaTypes.php b/app/code/Magento/Swagger/Block/SchemaTypes.php deleted file mode 100644 index f9d9cd795119c..0000000000000 --- a/app/code/Magento/Swagger/Block/SchemaTypes.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Swagger\Block; - -use Magento\Framework\View\Element\Block\ArgumentInterface; -use Magento\Swagger\Api\Block\SchemaTypesInterface; -use Magento\Swagger\Api\SchemaTypeInterface; - -/** - * Schema Type Options. - */ -class SchemaTypes implements SchemaTypesInterface, ArgumentInterface -{ - /** - * @var SchemaTypeInterface - */ - private $default; - /** - * @var SchemaTypeInterface[]|null - */ - private $types; - - /** - * SchemaTypes constructor. - * - * @param array|SchemaTypeInterface[] $types - */ - public function __construct( - array $types = [] - ) { - $this->types = $types; - if (count($this->types) > 0) { - $this->default = array_values($this->types)[0]; - } - } - - /** - * Retrieve the available types of Swagger schema. - * - * @return SchemaTypeInterface[] - */ - public function getTypes() - { - return $this->types; - } - - /** - * Retrieve the default schema type for Swagger. - * - * @return SchemaTypeInterface|null - */ - public function getDefault() - { - return $this->default; - } -} diff --git a/app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php b/app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php index 9746cfac73cd0..a1955f6c2a3b8 100644 --- a/app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php +++ b/app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php @@ -12,6 +12,7 @@ use Magento\Swagger\Api\SchemaTypeInterface; use Magento\Swagger\Block\Index; use Magento\Swagger\Block\SchemaTypes; +use Magento\SwaggerWebapi\Model\SchemaType\Rest; class IndexTest extends \PHPUnit\Framework\TestCase { @@ -48,12 +49,9 @@ protected function setUp() ] ), 'data' => [ - 'schema_types' => (new ObjectManager($this))->getObject( - SchemaTypes::class, - [ - 'types' => [$this->schemaTypeMock] - ] - ) + 'schema_types' => [ + 'rest' => (new ObjectManager($this))->getObject(Rest::class) + ] ] ] ); @@ -81,7 +79,7 @@ public function testGetSchemaUrlValidType() } /** - * Test that the passed URL parameter is not used when it is not a valid schema type. + * Test that Swagger UI throws an exception if an invalid schema type is supplied. * * @covers \Magento\Swagger\Block\Index::getSchemaUrl() */ @@ -94,10 +92,8 @@ public function testGetSchemaUrlInvalidType() $this->schemaTypeMock->expects($this->any()) ->method('getCode')->willReturn('test'); - $this->schemaTypeMock->expects($this->once()) - ->method('getSchemaUrlPath') - ->willReturn('/test'); + $this->expectException(\UnexpectedValueException::class); - $this->assertEquals('/test', $this->index->getSchemaUrl()); + $this->index->getSchemaUrl(); } } diff --git a/app/code/Magento/Swagger/Test/Unit/Block/SchemaTypesTest.php b/app/code/Magento/Swagger/Test/Unit/Block/SchemaTypesTest.php deleted file mode 100644 index 5ccbd777d17f6..0000000000000 --- a/app/code/Magento/Swagger/Test/Unit/Block/SchemaTypesTest.php +++ /dev/null @@ -1,62 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Store\Test\Unit\Block; - -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use Magento\Swagger\Api\SchemaTypeInterface; -use Magento\Swagger\Block\SchemaTypes; - -class SchemaTypesTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var SchemaTypeInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $defaultType; - - /** - * @var SchemaTypes - */ - private $schemaTypes; - - /** - * @inheritdoc - */ - protected function setUp() - { - $this->defaultType = $this->getMockBuilder(SchemaTypeInterface::class) - ->getMock(); - - $this->schemaTypes = (new ObjectManager($this))->getObject( - SchemaTypes::class, - [ - 'types' => [ - $this->defaultType, - $this->getMockBuilder(SchemaTypeInterface::class)->getMock() - ] - ] - ); - } - - /** - * @covers \Magento\Swagger\Block\SchemaTypes::getTypes() - */ - public function testGetTypes() - { - $this->assertCount(2, $this->schemaTypes->getTypes()); - $this->assertContains($this->defaultType, $this->schemaTypes->getTypes()); - } - - /** - * Test that the first type supplied to SchemaTypes is the default - * - * @covers \Magento\Swagger\Block\SchemaTypes::getDefault() - */ - public function testGetDefaultType() - { - $this->assertEquals($this->defaultType, $this->schemaTypes->getDefault()); - } -} diff --git a/app/code/Magento/Swagger/composer.json b/app/code/Magento/Swagger/composer.json index 5ea14336944d9..6021baea8ad9f 100644 --- a/app/code/Magento/Swagger/composer.json +++ b/app/code/Magento/Swagger/composer.json @@ -6,10 +6,11 @@ }, "require": { "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", - "magento/framework": "100.3.*" + "magento/framework": "100.3.*", + "magento/module-webapi": "100.3.*", }, "type": "magento2-module", - "version": "100.3.0-dev", + "version": "100.0.0", "license": [ "OSL-3.0", "AFL-3.0" @@ -19,7 +20,7 @@ "registration.php" ], "psr-4": { - "Magento\\Swagger\\": "" + "Magento\\SwaggerWebapi\\": "" } } } diff --git a/app/code/Magento/Swagger/view/frontend/layout/swagger_index_index.xml b/app/code/Magento/Swagger/view/frontend/layout/swagger_index_index.xml index bd6fcb5facf8a..345f063a7aaa3 100644 --- a/app/code/Magento/Swagger/view/frontend/layout/swagger_index_index.xml +++ b/app/code/Magento/Swagger/view/frontend/layout/swagger_index_index.xml @@ -45,12 +45,7 @@ <referenceContainer name="page.wrapper" remove="true"/> <referenceBlock name="requirejs-config" remove="true"/> <referenceContainer name="root"> - <block name="swaggerUiContent" class="Magento\Swagger\Block\Index" template="Magento_Swagger::swagger-ui/index.phtml"> - <arguments> - <argument name="schema_types" xsi:type="object">Magento\Swagger\Api\Block\SchemaTypesInterface</argument> - </arguments> - </block> + <block name="swaggerUiContent" class="Magento\Swagger\Block\Index" template="Magento_Swagger::swagger-ui/index.phtml" /> </referenceContainer> </body> </page> - diff --git a/app/code/Magento/SwaggerWebapi/Model/SchemaType/Rest.php b/app/code/Magento/SwaggerWebapi/Model/SchemaType/Rest.php index 248a56bd09ed6..26c995f95103a 100644 --- a/app/code/Magento/SwaggerWebapi/Model/SchemaType/Rest.php +++ b/app/code/Magento/SwaggerWebapi/Model/SchemaType/Rest.php @@ -5,7 +5,7 @@ */ namespace Magento\SwaggerWebapi\Model\SchemaType; -use Magento\Swagger\Api\SchemaTypeInterface; +use Magento\Swagger\Api\Data\SchemaTypeInterface; /** * Rest swagger schema type. diff --git a/app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php b/app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php index 465870f331807..44b348cb57087 100644 --- a/app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php +++ b/app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php @@ -6,7 +6,7 @@ namespace Magento\SwaggerWebapi\Test\Unit\Model\SchemaType; -use Magento\Swagger\Api\SchemaTypeInterface; +use Magento\Swagger\Api\Data\SchemaTypeInterface; use Magento\SwaggerWebapi\Model\SchemaType\Rest; class RestTest extends \PHPUnit\Framework\TestCase diff --git a/app/code/Magento/SwaggerWebapi/etc/frontend/di.xml b/app/code/Magento/SwaggerWebapi/etc/frontend/di.xml index 5a487ddb41f68..4e680fe1a27f7 100644 --- a/app/code/Magento/SwaggerWebapi/etc/frontend/di.xml +++ b/app/code/Magento/SwaggerWebapi/etc/frontend/di.xml @@ -12,12 +12,4 @@ <argument name="code" xsi:type="string">rest</argument> </arguments> </type> - - <type name="Magento\Swagger\Block\SchemaTypes"> - <arguments> - <argument name="types" xsi:type="array"> - <item name="rest" xsi:type="object">Magento\SwaggerWebapi\Model\SchemaType\Rest</item> - </argument> - </arguments> - </type> </config> \ No newline at end of file diff --git a/app/code/Magento/SwaggerWebapi/etc/module.xml b/app/code/Magento/SwaggerWebapi/etc/module.xml index 1ab25b58ae8f9..b3a80d22de697 100644 --- a/app/code/Magento/SwaggerWebapi/etc/module.xml +++ b/app/code/Magento/SwaggerWebapi/etc/module.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_SwaggerWebapi" setup_version="0.0.1"> + <module name="Magento_SwaggerWebapi"> <sequence> <module name="Magento_Webapi" /> </sequence> diff --git a/app/code/Magento/SwaggerWebapi/view/frontend/layout/swagger_index_index.xml b/app/code/Magento/SwaggerWebapi/view/frontend/layout/swagger_index_index.xml new file mode 100644 index 0000000000000..4e6adf5f06fd9 --- /dev/null +++ b/app/code/Magento/SwaggerWebapi/view/frontend/layout/swagger_index_index.xml @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <body> + <referenceBlock name="swaggerUiContent"> + <arguments> + <argument name="schema_types" xsi:type="array"> + <item name="rest" xsi:type="object">Magento\SwaggerWebapi\Model\SchemaType\Rest</item> + </argument> + <argument name="default_schema_type_code" xsi:type="string">rest</argument> + </arguments> + </referenceBlock> + </body> +</page> diff --git a/dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/IndexTest.php b/dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/IndexTest.php index 5dd8aed539c8a..cf1c87e2b2225 100644 --- a/dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/IndexTest.php @@ -27,9 +27,12 @@ protected function setUp() '', [ 'data' => [ - 'schema_types' => \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Swagger\Api\Block\SchemaTypesInterface::class - ) + 'schema_types' => [ + 'rest' => \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\SwaggerWebapi\Model\SchemaType\Rest::class + ) + ], + 'default_schema_type_code' => 'rest' ] ] ); diff --git a/dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/SchemaTypesTest.php b/dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/SchemaTypesTest.php deleted file mode 100644 index 73307fdc1f486..0000000000000 --- a/dev/tests/integration/testsuite/Magento/SwaggerWebapi/Block/Swagger/SchemaTypesTest.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\SwaggerWebapi\Block\Swagger; - -use Magento\Swagger\Api\Block\SchemaTypesInterface; - -/** - * @magentoAppArea frontend - */ -class SchemaTypesTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Swagger\Block\SchemaTypes - */ - private $schemaTypes; - - protected function setUp() - { - \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\App\State::class) - ->setAreaCode('frontend'); - - $this->schemaTypes = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - SchemaTypesInterface::class - ); - } - - /** - * Test that the Swagger SchemaTypes contains the type added by SwaggerWebapi. - */ - public function testContainsSchemaType() - { - $schemaExists = function () { - foreach ($this->schemaTypes->getTypes() as $schemaType) { - if ($schemaType->getCode() === 'rest') { - return true; - } - } - return false; - }; - - $this->assertTrue($schemaExists()); - } -} From f33b11245caf9523ef2a59253994b60f85e40bfd Mon Sep 17 00:00:00 2001 From: Carey Sizer <carey@balanceinternet.com.au> Date: Fri, 23 Feb 2018 15:52:39 +1300 Subject: [PATCH 172/668] Added SwaggerWebapiAsync to allow WebapiAsync integration with WebapiAsync --- .../Magento/SwaggerWebapiAsync/LICENSE_EE.txt | 437 ++++++++++++++++++ .../Model/SchemaType/Async.php | 48 ++ app/code/Magento/SwaggerWebapiAsync/README.md | 1 + .../Test/Unit/Model/SchemaType/AsyncTest.php | 66 +++ .../Magento/SwaggerWebapiAsync/composer.json | 28 ++ .../SwaggerWebapiAsync/etc/frontend/di.xml | 23 + .../Magento/SwaggerWebapiAsync/etc/module.xml | 14 + .../SwaggerWebapiAsync/registration.php | 9 + .../Block/Swagger/IndexTest.php | 63 +++ .../Block/Swagger/SchemaTypesTest.php | 45 ++ 10 files changed, 734 insertions(+) create mode 100644 app/code/Magento/SwaggerWebapiAsync/LICENSE_EE.txt create mode 100644 app/code/Magento/SwaggerWebapiAsync/Model/SchemaType/Async.php create mode 100644 app/code/Magento/SwaggerWebapiAsync/README.md create mode 100644 app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php create mode 100644 app/code/Magento/SwaggerWebapiAsync/composer.json create mode 100644 app/code/Magento/SwaggerWebapiAsync/etc/frontend/di.xml create mode 100644 app/code/Magento/SwaggerWebapiAsync/etc/module.xml create mode 100644 app/code/Magento/SwaggerWebapiAsync/registration.php create mode 100644 dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/IndexTest.php create mode 100644 dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/SchemaTypesTest.php diff --git a/app/code/Magento/SwaggerWebapiAsync/LICENSE_EE.txt b/app/code/Magento/SwaggerWebapiAsync/LICENSE_EE.txt new file mode 100644 index 0000000000000..2bddf5feda6ba --- /dev/null +++ b/app/code/Magento/SwaggerWebapiAsync/LICENSE_EE.txt @@ -0,0 +1,437 @@ +MAGENTO(tm) ENTERPRISE EDITION +END USER LICENSE AGREEMENT + +This End User License Agreement ("Agreement") is entered into by and between X.commerce, Inc. +through its Magento division ("Magento"), and the Licensee executing the Magento Order Form +(defined below). The parties agree as follows: + +TERMS AND CONDITIONS + +1. License + 1.1. Subject to Licensee's payment of the applicable fees and to Licensee's compliance with + other terms and conditions of this Agreement, Magento grants Licensee a non-transferable, + non-assignable, non-sublicensable, worldwide license to copy the Software for the purpose of + installing and using it on a computer and solely for internal purposes, in accordance with the + Software's technical documentation and solely during the periods and on the maximum number + of Designated Servers specified in one or more applicable Magento or Magento-authorized + reseller ordering schedules (the "Magento Order Form") executed with Licensee. + + 1.2. In the event that Licensee's actual number of Servers of a particular Software license + exceeds the licensed number of Designated Servers on such license, Licensee shall promptly + provide Magento with written notice and pay Magento the fees required to license such + additional Server(s) in accordance with the commercial terms set out in the Magento Order + Form. + + 1.3. Licensee shall implement reasonable controls to ensure that it does not exceed the + maximum number of licensed Servers of the Software. Magento reserves the right to audit + Licensee's use of the Software during normal business hours and with reasonable notice and to + include means within the Software to limit Licensee's use of the Software to the licensed + number of Servers. + + 1.4. Magento shall provide to Licensee an initial copy of the Software, including the associated + technical documentation, for use by Licensee in accordance with this Agreement. Subject to + Sections 1.1-1.3 above, Licensee is authorized to make a reasonable number of non-Server + copies of the Software, e.g., onto a local pc, as it requires for purpose of exercising its rights + under this Agreement. + + 1.5. Licensee is authorized to use the Software on a single substitute or backup Server on a + temporary basis without charge any time a Designated Server is inoperative due to a + malfunction beyond the control of Licensee. Licensee may transfer the Software on a + permanent basis to a single replacement Server without charge. Licensee agrees to provide + Magento with written notice, including the Server type and operating system, of any such + transfer to a backup or replacement Server within five (5) days thereafter. + + 1.6. Licensee acknowledges that portions of the Software are also freely available to the public + under Magento's open source version of the Software, known as Magento Community Edition, + subject to certain conditions, with limited warranties and other limited assurances, and without + service or support. As an express condition for the license granted hereunder, Licensee agrees + that any use during the term of this Agreement of such open source versions of the Software, + whether in a Production Server Instance or a Non-Production Server Instance, shall be deemed + use of the Software for purposes of the calculation of fees payable under the Agreement. + + 1.7. Magento also grants Licensee the right to modify and create derivative works of the + Software. Licensee may contribute the rights in any of those derivative works back to Magento. + Licensee may contact Magento for more information regarding contributions of derivative + works rights to Magento. Regardless of whether Licensee contributes such derivative works + rights to Magento, Licensee hereby grants Magento a perpetual and irrevocable (irrespective of + the expiration or termination of this Agreement), nonexclusive, transferable, worldwide, and + royalty-free license to reproduce, create derivative works of, distribute, perform, and display + any derivative works of the Software developed by or for Licensee, and to use, make, have + made, sell, offer to sell, import, export, and otherwise exploit any product based on any such + derivative works. + +2. License Exclusions + 2.1 Except as expressly authorized herein, Licensee shall not: + a. use or deploy the Software on any Server in excess of the number of Designated Servers + specified in the applicable Magento Order Form; + + b. distribute, sublicense, disclose, market, rent, lease, or offer remote computing services, + networking, batch processing or transfer of, the Software to any third party, or permit any + person or entity to have access to the Software by means of a time sharing, remote + computing services, networking, batch processing, service bureau or time sharing + arrangement; + + c. export the Software in violation of U.S. Department of Commerce export administration + regulations. + + 2.2. No license, right or interest in any Magento trademark, trade name or service mark is + granted hereunder. + +3. Fees and Payment Terms + Licensee agrees to the fees and payment terms that are described in each Magento Order Form + executed by Licensee. + +4. Title and Protection + 4.1. Magento (or its third party providers) retains title to all portions of the Software and other + Proprietary Materials and any copies thereof. The Proprietary Materials contain valuable + proprietary information, and Licensee shall not disclose them to anyone other than those of its + employees or consultants under written nondisclosure obligations at least as restrictive as + those contained in this Agreement, having a need to know for purposes consistent with this + Agreement. Licensee shall be responsible for the compliance of such employees or consultants. + Licensee shall affix, to each full or partial copy of the Software made by Licensee, all copyright + and proprietary information notices as were affixed to the original. The obligations set forth in + this Section shall survive termination of this Agreement. + + 4.2. Licensee acknowledges that the Software includes certain open source software which is + governed by the applicable license terms thereof. A list of such open source software, as + amended from time to time, including the links applicable to such open source software is + specified in the product software bundled within the Software, and the Software is subject to + the provisions of such license agreements, and in the event of any contradiction between the + provisions of this Agreement and the provisions of such applicable license agreement, the + provisions of the applicable open source license agreement shall prevail solely with respect to + such open source software products. + + 4.3. If the Software is acquired by or on behalf of a unit or agency of the U.S. Government (the + "Government"), the Government agrees that such Product is "commercial computer software" + or "commercial computer software documentation" and that, absent a written agreement to + the contrary, the Government's rights with respect thereto are limited by the terms of this + Agreement, pursuant to applicable FAR and/or DFARS and successor regulations. + +5. Patent and Copyright Indemnity + Subject to the limitations in Section 8, for such time as Licensee is entitled to receive Support + Services (as defined below), Magento shall indemnify and defend Licensee against any claims made + by a third party that Licensee's reproduction of the Software (which, for the purposes of this Section + 5, means the Software as delivered by Magento, excluding the open source software programs + described in Section 4.2) as permitted in this Agreement directly infringes such third party's United + States patent or copyright, provided that Licensee complies with the requirements of this Section. + Licensee will (a) provide Magento prompt written notice of any claim that the Software infringes any + intellectual property rights, (b) provide Magento with all information and assistance requested of it + with respect to any such claim, and (c) offer Magento sole and complete authority to defend and/or + settle any and all such claims. + + In the event that a court holds that the Software, or if Magento believes a court may hold that the + Software, infringes the intellectual property rights of any third party, Magento may (but is not + obligated to), in its sole discretion, do any of the following: obtain for Licensee the right to continue + using the Software, replace or modify the Software so that it becomes non-infringing while providing + substantially equivalent performance or, accept return of the Software, terminate this Agreement, + and refund Licensee an amount equal to the license fees paid to Magento multiplied by the + percentage of the term of the license for the Software that Licensee did not enjoy due to the early + termination by Magento. + + Magento shall have no liability or obligation under this Agreement to the extent the alleged + infringement is based on (i) a modification or derivative work of the Software developed by anyone + other than Magento; (ii), a combination of the Software with any product or service not provided by + Magento; (ii) use of the Software with one or more Servers not listed in a Magento Order Form; (iii) + use of the Software other than in accordance with this Agreement or the documentation; (iv) + indirect or willful infringement; or (v) any open source code, as described in Section 4.2. + + This Section 5 states Magento's entire liability and Licensee's exclusive remedy for any infringement + related to the Software. + +6. Default and Termination + 6.1. An event of default shall be deemed to occur if: (i) Licensee fails to perform any of its + obligations under the Sections entitled "License Exclusions" or "Title and Protection"; (ii) + Licensee fails to pay amounts due pursuant to its agreement to the fees and payment terms in + Section 3 of this Agreement within seven (7) days of the relevant due date; or (iii) either party + fails to perform any other material obligation under this Agreement and such failure remains + uncured for more than thirty (30) days after receipt of written notice thereof. + + 6.2. If an event of default occurs, the non-defaulting party, in addition to any other rights + available to it under the law, may terminate this Agreement and all licenses granted hereunder + by written notice to the defaulting party. + + 6.3. Within thirty (30) days after termination of the Software license or this Agreement or + expiration of the license term as specified in the Magento Order Form, Licensee shall certify in + writing to Magento that Licensee has ceased use of any and all Proprietary Materials and that + all copies or embodiments thereof in any form, including partial copies within modified + versions, have been destroyed. + +7. Warranty + 7.1. Warranty for Software. Magento warrants for a single period of ninety (90) days + commencing upon Magento's electronic delivery of the Software to Licensee that the Software, + as delivered, will in all material respects perform the functions described in the specifications + contained in the documentation provided with the Software. In the event that the Software + does not, in all material respects, perform the functions therein described, Magento or its + authorized reseller will undertake to correct any reported error in accordance with the Support + Services Terms and Conditions set forth below in Section 9, which shall be Magento's entire + liability and Licensee's exclusive remedy for breach of this warranty. Magento does not warrant + that the Software will meet Licensee's requirements, that the Software will operate in the + combinations which Licensee may select for use, that the operation of the Software will be + uninterrupted or error-free, or that all error conditions will be corrected. EXCEPT AS PROVIDED + IN THIS SECTION ALL SOFTWARE PROVIDED HEREUNDER IS PROVIDED "AS IS". + + 7.2. DISCLAIMER. THE EXPRESS WARRANTIES SET FORTH IN THIS SECTION 7 ARE THE ONLY + WARRANTIES MADE BY MAGENTO WITH RESPECT TO THE SOFTWARE PROVIDED BY MAGENTO. + MAGENTO MAKES NO OTHER WARRANTIES, EXPRESS, IMPLIED OR ARISING BY CUSTOM OR + TRADE USAGE, AND, SPECIFICALLY, MAKES NO WARRANTY OF TITLE, NON-INFRINGEMENT, + ACCURACY, QUIET ENJOYMENT, MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR + PURPOSE. MAGENTO'S EXPRESS WARRANTIES SHALL NOT BE ENLARGED, DIMINISHED OR + AFFECTED BY, AND NO OBLIGATION OR LIABILITY SHALL ARISE OUT OF, MAGENTO RENDERING + TECHNICAL OR OTHER ADVICE OR SERVICE IN CONNECTION WITH THE SOFTWARE. + +8. Limitation of Liability + 8.1. LIABILITY EXCLUSIONS. UNDER NO CIRCUMSTANCES WILL MAGENTO BE LIABLE FOR: LOSS + OF REVENUE; LOSS OF ACTUAL OR ANTICIPATED PROFITS; LOSS OF CONTRACTS; LOSS OF THE + USE OF MONEY; LOSS OF ANTICIPATED SAVINGS; LOSS OF BUSINESS; LOSS OF OPPORTUNITY; + LOSS OF GOODWILL; LOSS OF REPUTATION; LOSS OF, DAMAGE TO OR CORRUPTION OF DATA; + OR CONSEQUENTIAL OR INDIRECT LOSS OR SPECIAL, PUNITIVE, OR INCIDENTAL DAMAGES + (INCLUDING, FOR THE AVOIDANCE OF DOUBT, WHERE SUCH LOSS OR DAMAGE IS ALSO OF A + CATEGORY OF LOSS OR DAMAGE ALREADY LISTED), WHETHER FORESEEABLE OR + UNFORESEEABLE, BASED ON CLAIMS OF LICENSEE, MAGENTO OR ANY THIRD PARTY ARISING + OUT OF ANY BREACH OR FAILURE OF EXPRESS OR IMPLIED WARRANTY CONDITIONS OR OTHER + TERM, BREACH OF CONTRACT, MISREPRESENTATION, NEGLIGENCE, OTHER LIABILITY IN TORT, + FAILURE OF ANY REMEDY TO ACHIEVE ITS ESSENTIAL PURPOSE, OR OTHERWISE. + + 8.2. LIABILITY CAP. NOTWITHSTANDING THE FORM (E.G., CONTRACT, TORT, OR OTHERWISE) IN + WHICH ANY LEGAL OR EQUITABLE ACTION MAY BE BROUGHT, IN NO EVENT (INCLUDING WITH + RESPECT TO OBLIGATIONS ARISING UNDER SECTION 5) WILL MAGENTO OR ITS SUPPLIERS BE + LIABLE FOR DAMAGES, EXPENSES, COSTS, LIABILITIES, SUITS, CLAIMS, RESTITUTION OR LOSSES, + THAT EXCEED, IN THE AGGREGATE, THE AMOUNT OF FEES PAID BY LICENSEE FOR THE + SOFTWARE LICENSE IN THE FIRST TWELVE (12) MONTH PERIOD AFTER THE EFFECTIVE DATE. + +9. Support Services Terms and Conditions + For the periods specified in the Magento Order Form, Magento or its authorized reseller will provide + support services and Updates for the Software as described in Magento's standard Support Services + Terms and Conditions, which follow. Magento will have no obligation to provide support for any + modifications or derivative works of the Software developed by anyone other than Magento. + +10. Customer References + Licensee hereby grants Magento the right to display Licensee's logos as part of Magento's customer + lists and other related marketing materials. The parties shall cooperate to undertake mutually- + agreed joint marketing activities. + +11. Notices + All notices shall be in writing and sent by first class mail or overnight mail (or courier), transmitted by + facsimile (if confirmed by such mailing), or email, to the addresses indicated on the Magento Order + Form, or such other address as either party may indicate by at least ten (10) days prior written + notice to the other party. Notices to Magento shall be sent to the Contracts Administration + Department. + +12. Assignment + Licensee may not assign this Agreement without the prior written consent of Magento; provided + that such consent shall not be required for assignment to a purchaser of all or substantially all of the + assets or equity securities of Licensee who undertakes in writing to be bound by all the terms and + conditions of this Agreement. Any prohibited assignment shall be null and void. + +13. Entire Agreement + Along with Magento's standard Support Services Terms and Conditions, which follow, and the + Magento Order Form, this Agreement is the complete and exclusive agreement between the parties, + which supersedes all proposals or prior agreements, oral or written, including any online (click- + through) agreement which Licensee may have accepted in conjunction with the downloading of the + Software, and all other communications between the parties relating to the subject matter hereof. + No purchase order, other ordering document or any hand written or typewritten text which purports + to modify or supplement the printed text hereof or Magento Order Form shall add to or vary the + terms thereof and Magento hereby rejects same. Except as contained in a writing signed by both + parties, all such proposed variations or additions are objected to and shall have no force or effect. + +14. General + This Agreement is made in and shall be governed by the laws of the State of California, without + giving effect to any principles that provide for the application of the law of another jurisdiction. All + proceedings shall be conducted in English. Venue for all proceedings shall be Santa Clara County, + California, provided that Magento may seek injunctive relief in any court of competent jurisdiction. + The United Nations Convention for the International Sale of Goods shall not apply. The section + headings herein are provided for convenience only and have no substantive effect on the + construction of this Agreement. Except for Licensee's obligation to pay Magento, neither party shall + be liable for any failure to perform due to causes beyond its reasonable control. If any provision of + this Agreement is held to be unenforceable, this Agreement shall be construed without such + provision. The failure by a party to exercise any right hereunder shall not operate as a waiver of such + party's right to exercise such right or any other right in the future. This Agreement may be amended + only by a written document executed by a duly authorized representative of each of the parties. The + parties agree to receive electronic documents and accept electronic signatures (information + attached or logically associated with such document and clicked or otherwise adopted with an intent + to sign) including in counterparts which shall be valid substitutes for paper-based documents and + signatures, and the legal validity of a transaction will not be denied on the ground that it is not in + writing. + +15. Definitions + "Designated Server" shall mean the Server specified in a Magento Order Form with respect to a + particular Software license. Such Server may be that of a third-party under nondisclosure obligations + that will host the Software for the benefit of Licensee. + + "Modifications" means any code developed by Licensee or any third party, including without + limitation, configuration, integrations, implementations, or localizations to the external layer of the + core, baseline Software product. The term "Modifications" excludes Updates. + + "Proprietary Material" means the Software, related documentation, and all parts, copies and + modifications thereof, and any other information, in whatever form, received by Licensee + hereunder, provided, however, such information shall not be deemed Proprietary Material if it (a) is + or becomes a part of the public domain through no act or omission of Licensee; or (b) was in + Licensee's lawful possession prior to the disclosure and had not been obtained by Licensee from + Magento; or (c) is lawfully disclosed to Licensee by a third party without restriction on disclosure; or + (d) is independently developed by Licensee without reference to or use of Magento's Proprietary + Material. + + "Server" means each physical or virtual server from which a single instance of the Software is + accessed and used either for production purposes ("Production Server Instance") or for non- + production purposes, such as development, testing, training and other non-operational business + transactions ("Non-Production Server Instance"). For example, if one server contains two (2) + instances of the Software, i.e., one Production Server Instance and one Non-Production Server + Instance, then a Server license is required for each of such instances; development in-house and by + third-party consultants requires licenses for two Non-Production Server Instances. + + "Software" means Magento's proprietary e-commerce software solution known as the Magento(tm) + Enterprise Edition, provided solely in source code, including associated technical documentation, + and all Updates thereof furnished to Licensee as part of Support Services. Except as otherwise + specified herein, the term Software includes certain open source software programs described in + Section 4.2. "Software" does not include any Modifications. + + "Updates" means all published revisions and corrections to the printed documentation and + corrections and new releases of the Software which are generally made available to Magento's + supported customers at no additional cost or for media and handling charges only. Updates shall not + include any options or future products which Magento sells separately. + + +SUPPORT SERVICES TERMS AND CONDITIONS + +Unless otherwise defined herein, all capitalized terms will have the meanings set forth in the +Agreement. + +1. "Support Services" consists of: + a. Advice regarding the downloading, installation and configuration of the Software (including + Updates provided by Magento, but excluding for the avoidance of doubt any Modifications to + the Software), when used by Licensee on systems that meet the Software's "System + Requirements" specified on Magento's website at www.magentocommerce.com/system- + requirements. + + b. Facilities for bug tracking, escalation of problems for priority attention, and access to + community-supported FAQs and Forums relating to the Software. + + c. Assistance with troubleshooting to diagnose and fix errors in the Software. + + d. Access to Magento documentation relating to the Software, including authorization to make + copies of that documentation for internal use as specified in the Agreement. + +2. Exclusions from Support Services. + Magento shall have no obligation to support (i) versions of the + Software other than the then-current and immediately previous releases, which are operated on a + supported hardware/operating system platform specified in the release notes for the Software; (ii) + altered or modified Software; (iii) Software accessed on unlicensed Servers; (iv) problems caused by + Licensee's negligence, misuse, or hardware malfunction; or (v) use of the Software inconsistent with + Magento's instructions. Magento is not responsible for hardware changes necessitated by changes + to the Software. Support Services does not include: + a. Assistance in the development or debugging of Licensee's system, including the operating + system and support tools. + + b. Information and assistance on technical issues related to the installation, administration, and + use of enabling technologies such as databases, computer networks, and communications. + + c. Assistance with the installation and configuration of hardware including, but not limited to + computers, hard disks, networks, and printers. + +3. Subcontractors. + Magento or its authorized resellers reserve the right to subcontract any or all of + the work to be performed under these Support Terms, and Magento retains responsibility for any + work so subcontracted. + +4. Licensee Responsibilities. + Licensee shall provide commercially reasonable cooperation and full + information to Magento or its authorized resellers with respect to the furnishing of Support Services + under this Agreement. + +5. Support Contacts. + Licensee shall designate one or more support contacts that are authorized to + submit Software problems. If Licensee has purchased the license from a Magento-authorized + reseller, Licensee shall contact that party for assistance. If Licensee has purchased the license + directly from Magento, Licensee may contact Magento on the www.magentocommere.com website + or at its toll-free Support telephone number. + +6. Problem Priority. + Upon receipt of a properly submitted Software problem, as specified on + Magento's website at www.magentocommerce.com, Magento or its authorized reseller shall + prioritize it in accordance with the guidelines below: + + a. Priority 1 (P1) - A P1 is a catastrophic production problem within the Software that severely + impacts the Licensee's Production Server Instance, or because of which Licensee's Production + Server Instance is down or not functioning, or that results in a loss of production data and no + work around exists. P1 problems must be reported on Magento's toll-free support telephone + number in order to expedite resolution. Magento will use continuous efforts during its normal + hours of operation, with appropriate escalation to senior management, to provide a resolution + for any P1 problem as soon as is commercially reasonable. + + b. Priority 2 (P2) - A P2 is a problem within the Software where the Licensee's system is + functioning but in a reduced capacity, or the Problem is causing significant impact to portions of + the Licensee's business operations and productivity, or the Software is exposed to potential loss + or interruption of service. Problems existing in a non-production environment that would + otherwise qualify as a P1 if they were in a production system qualify as P2. Magento will use + reasonable efforts during its normal hours of operation to provide a resolution for any P2 + problem as soon as is commercially reasonable. + + c. Priority 3 (P3) - A P3 is a medium-to-low impact problem that involves partial and/or non- + critical loss of functionality, or that impairs some operations but allows Licensee's operations to + continue to function. Problems for which there is limited or no loss or functionality or impact to + Licensee's operation and for which there is an easy work-around qualify as P3. Magento will use + reasonable efforts during its normal hours of operation to provide a resolution for any P3 + problem in time for the next minor release of the Software. + + d. Priority 4 (P4) - A P4 is for a general usage question or issue that may be cosmetic in nature + or documentation related, but the Software works without normal hours of operation to + provide a resolution for any P4 problem in time for the next major release of the Software. + + e. Enhancement Request (ER) - An ER is a recommendation for future product enhancement or + modification to add official support and documentation for unsupported or undocumented + feature, or features that do not exist in the Software. Magento will take ERs into consideration + in the product management process, but has no obligation to deliver enhancements based on + any ER. + +7. Response Times. + Magento or its authorized reseller shall exercise commercially reasonable efforts + to meet the response times specified below for Gold Support (unless Licensee has upgraded to + Platinum Support, as provided in the Magento Order Form), following receipt of a Software problem + properly submitted by Licensee: + + Magento GOLD Support Response Times + WEB Ticket Submission 24 x 7 x 365 + WEB Ticket Response Time* 24 business hours + North American Telephone Support Hours M-F 08:00 - 17:00 (PT) + European Telephone Support Hours M-F 08:30 - 17:30 (CET) + Telephone Response Time P1 Issues* 4 business hours + Response Time P2-P4 Issues* 24 business hours + *From initial contact + + + Magento PLATINUM Support Response Times + WEB Ticket Submission 24 x 7 x 365 + WEB Ticket Response Time* 24 business hours + Telephone Support Hours 24 hours + Telephone Response Time P1 Issues* Up to 2 hours + Response Time P2-P4 Issues* 4 business hours + *From initial contact + + +8. Prohibited Use. + As a condition of Licensee's use of the Forums, Licensee will not use (and will + prohibit its customers from using) the Forums (i) to violate any applicable law, statute, ordinance or + regulation; (ii) to disseminate content that is harmful, threatening, abusive, harassing, tortuous, + defamatory, vulgar, obscene, libelous, or otherwise objectionable; (iii) to disseminate any software + viruses or any other computer code, files or programs that may interrupt, destroy or limit the + functionality of any computer software or hardware or telecommunications equipment; (iv) to + infringe the intellectual property rights or proprietary rights, or rights of publicity or privacy, of any + third party; or (v) use the Forums for any purpose other than their intended use. + +9. Term and Termination. + Magento will provide Support Services and any Updates to Licensee + during the periods identified in the Magento Order Form, subject to Licensee's payment of the + applicable fees. In the event Licensee fails to pay such fees to Magento or in the event Licensee + materially breaches the Support Services provisions and does not cure such breach within thirty (30) + days of its receipt of Magento's notice of same, Magento may suspend or cancel Support Services. + +10. General. + Magento shall not be liable for any failure or delay in performance under these Support + Terms due to causes beyond its reasonable control. Any illegal or unenforceable provision shall be + severed from these Support Terms. Licensee agrees that any information received pursuant to these + Support Terms shall be deemed to be subject to the non-disclosure obligations set forth in the + License Agreement. Licensee's obligation of payment of moneys due under these Support Terms + shall survive termination of these Support Terms or the License Agreement. These Support Terms + state the entire agreement regarding provision of Support Services to Licensee and may be amended + only by a written amendment set forth on a separate document executed by authorized + representatives of both parties. diff --git a/app/code/Magento/SwaggerWebapiAsync/Model/SchemaType/Async.php b/app/code/Magento/SwaggerWebapiAsync/Model/SchemaType/Async.php new file mode 100644 index 0000000000000..b89d08ebfcaec --- /dev/null +++ b/app/code/Magento/SwaggerWebapiAsync/Model/SchemaType/Async.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SwaggerWebapiAsync\Model\SchemaType; + +use Magento\Swagger\Api\SchemaTypeInterface; + +/** + * Async swagger schema type. + */ +class Async implements SchemaTypeInterface +{ + /** + * @var string + */ + private $code; + + /** + * Async constructor. + * + * @param string $code + */ + public function __construct(string $code) + { + $this->code = $code; + } + + /** + * @return string + */ + public function getCode() + { + return $this->code; + } + + /** + * @param string|null $store + * @return string + */ + public function getSchemaUrlPath($store = null) + { + $store = $store ?? 'all'; + + return '/' . $this->code . '/' . $store . '/schema?services=all'; + } +} diff --git a/app/code/Magento/SwaggerWebapiAsync/README.md b/app/code/Magento/SwaggerWebapiAsync/README.md new file mode 100644 index 0000000000000..373733639c65c --- /dev/null +++ b/app/code/Magento/SwaggerWebapiAsync/README.md @@ -0,0 +1 @@ +The Magento_SwaggerWebapiAsync module provides the implementation of the Asynchronous WebApi module with Magento_Swagger. \ No newline at end of file diff --git a/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php b/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php new file mode 100644 index 0000000000000..bac2625fa289e --- /dev/null +++ b/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\SwaggerWebapi\Test\Unit\Model\SchemaType; + +use Magento\Swagger\Api\SchemaTypeInterface; +use Magento\SwaggerWebapi\Model\SchemaType\Async; + +class AsyncTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var SchemaTypeInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $async; + + /** + * @inheritdoc + */ + protected function setUp() + { + // @todo: implement constant once merged with other bulk-api changes + $this->async = new Async('async'); + } + + /** + * @covers \Magento\SwaggerWebapi\Model\SchemaType\Async::getCode() + */ + public function testGetCode() + { + // @todo: implement constant once merged with other bulk-api changes + $this->assertEquals('async', $this->async->getCode()); + } + + /** + * @covers \Magento\SwaggerWebapi\Model\SchemaType\Async::getSchemaUrlPathProvider + * + * @param null|string $store + * @param $expected + * + * @dataProvider getSchemaUrlPathProvider + */ + public function testGetSchemaUrlPath($store = null, $expected) + { + $this->assertEquals($expected, $this->async->getSchemaUrlPath($store)); + } + + /** + * @return array + */ + public function getSchemaUrlPathProvider() + { + return [ + [ + null, + '/async/all/schema?services=all' + ], + [ + 'test', + '/async/test/schema?services=all' + ] + ]; + } +} diff --git a/app/code/Magento/SwaggerWebapiAsync/composer.json b/app/code/Magento/SwaggerWebapiAsync/composer.json new file mode 100644 index 0000000000000..6ca412c3f717c --- /dev/null +++ b/app/code/Magento/SwaggerWebapiAsync/composer.json @@ -0,0 +1,28 @@ +{ + "name": "magento/module-swagger-webapi-async", + "description": "N/A", + "config": { + "sort-packages": true + }, + "require": { + "magento/framework": "100.3.*", + "magento/module-swagger": "100.3.*", + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" + }, + "suggest": { + "magento/module-config": "100.3.*" + }, + "type": "magento2-module", + "version": "100.3.0-dev", + "license": [ + "proprietary" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\SwaggerWebapiAsync\\": "" + } + } +} diff --git a/app/code/Magento/SwaggerWebapiAsync/etc/frontend/di.xml b/app/code/Magento/SwaggerWebapiAsync/etc/frontend/di.xml new file mode 100644 index 0000000000000..f1ee30ba60bb1 --- /dev/null +++ b/app/code/Magento/SwaggerWebapiAsync/etc/frontend/di.xml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <type name="Magento\SwaggerWebapiAsync\Model\SchemaType\Async"> + <arguments> + <!-- @todo: implement constant once merged with other bulk-api changes --> + <argument name="code" xsi:type="string">async</argument> + </arguments> + </type> + + <type name="Magento\Swagger\Block\SchemaTypes"> + <arguments> + <argument name="types" xsi:type="array"> + <item name="async" xsi:type="object">Magento\SwaggerWebapiAsync\Model\SchemaType\Async</item> + </argument> + </arguments> + </type> +</config> \ No newline at end of file diff --git a/app/code/Magento/SwaggerWebapiAsync/etc/module.xml b/app/code/Magento/SwaggerWebapiAsync/etc/module.xml new file mode 100644 index 0000000000000..7e176a552cbf2 --- /dev/null +++ b/app/code/Magento/SwaggerWebapiAsync/etc/module.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> + <module name="Magento_SwaggerWebapiAsync" setup_version="0.0.1"> + <sequence> + <module name="Magento_WebapiAsync" /> + </sequence> + </module> +</config> diff --git a/app/code/Magento/SwaggerWebapiAsync/registration.php b/app/code/Magento/SwaggerWebapiAsync/registration.php new file mode 100644 index 0000000000000..05a468117210f --- /dev/null +++ b/app/code/Magento/SwaggerWebapiAsync/registration.php @@ -0,0 +1,9 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use \Magento\Framework\Component\ComponentRegistrar; + +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_SwaggerWebapiAsync', __DIR__); diff --git a/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/IndexTest.php b/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/IndexTest.php new file mode 100644 index 0000000000000..97c5fa6590975 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/IndexTest.php @@ -0,0 +1,63 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SwaggerWebapiAsync\Block\Swagger; + +/** + * @magentoAppArea frontend + */ +class IndexTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Swagger\Block\Index + */ + private $block; + + protected function setUp() + { + \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\App\State::class) + ->setAreaCode('frontend'); + + $this->block = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Framework\View\LayoutInterface::class + )->createBlock( + \Magento\Swagger\Block\Index::class, + '', + [ + 'data' => [ + 'schema_types' => \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Swagger\Api\Block\SchemaTypesInterface::class + ) + ] + ] + ); + } + + /** + * Test that Swagger UI outputs the all store code when it is specified. + */ + public function testSchemaUrlOutput() + { + $this->block->getRequest()->setParams([ + 'type' => 'async', + 'store' => 'custom', + ]); + + $this->assertStringEndsWith('/async/all/schema?services=all', $this->block->getSchemaUrl()); + } + + /** + * Test that Swagger UI outputs the supplied store code when it is specified. + */ + public function testSchemaUrlOutputWithStore() + { + $this->block->getRequest()->setParams([ + 'type' => 'async', + 'store' => 'custom', + ]); + + $this->assertStringEndsWith('/async/custom/schema?services=all', $this->block->getSchemaUrl()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/SchemaTypesTest.php b/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/SchemaTypesTest.php new file mode 100644 index 0000000000000..f1e5ddfa86882 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/SchemaTypesTest.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\SwaggerWebapiAsync\Block\Swagger; + +/** + * @magentoAppArea frontend + */ +class SchemaTypesTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Swagger\Block\SchemaTypes + */ + private $schemaTypes; + + protected function setUp() + { + \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\App\State::class) + ->setAreaCode('frontend'); + + $this->schemaTypes = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Swagger\Api\Block\SchemaTypesInterface::class + ); + } + + /** + * Test that the Swagger SchemaTypes contains the type added by SwaggerWebapiAsync. + */ + public function testContainsSchemaType() + { + $schemaExists = function() { + foreach ($this->schemaTypes->getTypes() as $schemaType) { + // @todo: implement constant once merged with other bulk-api changes + if ($schemaType->getCode() === 'async') { + return true; + } + } + return false; + }; + + $this->assertTrue($schemaExists()); + } +} From cc6ca207a3e67cda65894c0703b27167746ddecd Mon Sep 17 00:00:00 2001 From: Carey Sizer <carey@balanceinternet.com.au> Date: Fri, 23 Feb 2018 15:52:39 +1300 Subject: [PATCH 173/668] Added SwaggerWebapiAsync to allow WebapiAsync integration with WebapiAsync Added WebapiAsync configuration locator, converter and reader Draft implementation of ServiceMetadata plugin for WebapiAsync Changes to SwaggerwebapiAsync and WebapiAsync modules Refactored WebapiAsync Config to ServiceConfig - Extracted methods from ServiceConfig::convert() for readability - Renamed Config to ServiceConfig to avoid conflicts with topic-related config --- .../Swagger/Test/Unit/Block/IndexTest.php | 3 +- app/code/Magento/Swagger/composer.json | 4 +- app/code/Magento/Swagger/etc/frontend/di.xml | 10 -- app/code/Magento/SwaggerWebapi/composer.json | 4 +- .../Model/SchemaType/Async.php | 2 +- .../Test/Unit/Model/SchemaType/AsyncTest.php | 2 +- .../Magento/SwaggerWebapiAsync/composer.json | 3 +- .../SwaggerWebapiAsync/etc/frontend/di.xml | 8 - .../Magento/SwaggerWebapiAsync/etc/module.xml | 4 +- .../frontend/layout/swagger_index_index.xml | 18 ++ .../WebapiAsync/Model/ServiceConfig.php | 79 +++++++++ .../Model/ServiceConfig/Converter.php | 167 ++++++++++++++++++ .../Model/ServiceConfig/Reader.php | 53 ++++++ .../Model/ServiceConfig/SchemaLocator.php | 56 ++++++ .../WebapiAsync/Plugin/ServiceMetadata.php | 147 +++++++++++++++ .../Model/ServiceConfig/ConverterTest.php | 30 ++++ .../Unit/Model/ServiceConfig/ReaderTest.php | 58 ++++++ .../Model/ServiceConfig/SchemaLocatorTest.php | 49 +++++ .../_files/Converter/webapi_async.php | 22 +++ .../_files/Converter/webapi_async.xml | 19 ++ .../_files/Reader/webapi_async.php | 22 +++ .../_files/Reader/webapi_async_1.xml | 18 ++ .../_files/Reader/webapi_async_2.xml | 12 ++ .../Test/Unit/Model/ServiceConfigTest.php | 96 ++++++++++ .../Magento/WebapiAsync/etc/frontend/di.xml | 14 ++ .../Magento/WebapiAsync/etc/webapi_async.xsd | 27 +++ 26 files changed, 898 insertions(+), 29 deletions(-) delete mode 100644 app/code/Magento/Swagger/etc/frontend/di.xml create mode 100644 app/code/Magento/SwaggerWebapiAsync/view/frontend/layout/swagger_index_index.xml create mode 100644 app/code/Magento/WebapiAsync/Model/ServiceConfig.php create mode 100644 app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php create mode 100644 app/code/Magento/WebapiAsync/Model/ServiceConfig/Reader.php create mode 100644 app/code/Magento/WebapiAsync/Model/ServiceConfig/SchemaLocator.php create mode 100644 app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php create mode 100644 app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ConverterTest.php create mode 100644 app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ReaderTest.php create mode 100644 app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/SchemaLocatorTest.php create mode 100644 app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.php create mode 100644 app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.xml create mode 100644 app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async.php create mode 100644 app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_1.xml create mode 100644 app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_2.xml create mode 100644 app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfigTest.php create mode 100644 app/code/Magento/WebapiAsync/etc/frontend/di.xml create mode 100644 app/code/Magento/WebapiAsync/etc/webapi_async.xsd diff --git a/app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php b/app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php index a1955f6c2a3b8..e2fd5e23d9480 100644 --- a/app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php +++ b/app/code/Magento/Swagger/Test/Unit/Block/IndexTest.php @@ -9,9 +9,8 @@ use Magento\Framework\App\RequestInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\View\Element\Template\Context; -use Magento\Swagger\Api\SchemaTypeInterface; +use Magento\Swagger\Api\Data\SchemaTypeInterface; use Magento\Swagger\Block\Index; -use Magento\Swagger\Block\SchemaTypes; use Magento\SwaggerWebapi\Model\SchemaType\Rest; class IndexTest extends \PHPUnit\Framework\TestCase diff --git a/app/code/Magento/Swagger/composer.json b/app/code/Magento/Swagger/composer.json index 6021baea8ad9f..6c69bb08ef59f 100644 --- a/app/code/Magento/Swagger/composer.json +++ b/app/code/Magento/Swagger/composer.json @@ -7,7 +7,7 @@ "require": { "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", "magento/framework": "100.3.*", - "magento/module-webapi": "100.3.*", + "magento/module-webapi": "100.3.*" }, "type": "magento2-module", "version": "100.0.0", @@ -20,7 +20,7 @@ "registration.php" ], "psr-4": { - "Magento\\SwaggerWebapi\\": "" + "Magento\\Swagger\\": "" } } } diff --git a/app/code/Magento/Swagger/etc/frontend/di.xml b/app/code/Magento/Swagger/etc/frontend/di.xml deleted file mode 100644 index 28ea4107d5453..0000000000000 --- a/app/code/Magento/Swagger/etc/frontend/di.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <preference for="Magento\Swagger\Api\Block\SchemaTypesInterface" type="Magento\Swagger\Block\SchemaTypes"/> -</config> \ No newline at end of file diff --git a/app/code/Magento/SwaggerWebapi/composer.json b/app/code/Magento/SwaggerWebapi/composer.json index 6650aad914bd5..e5e8112f3f063 100644 --- a/app/code/Magento/SwaggerWebapi/composer.json +++ b/app/code/Magento/SwaggerWebapi/composer.json @@ -10,7 +10,7 @@ "magento/module-swagger": "100.3.*" }, "type": "magento2-module", - "version": "100.3.0-dev", + "version": "100.0.0", "license": [ "OSL-3.0", "AFL-3.0" @@ -20,7 +20,7 @@ "registration.php" ], "psr-4": { - "Magento\\Swagger\\": "" + "Magento\\SwaggerWebapi\\": "" } } } diff --git a/app/code/Magento/SwaggerWebapiAsync/Model/SchemaType/Async.php b/app/code/Magento/SwaggerWebapiAsync/Model/SchemaType/Async.php index b89d08ebfcaec..1fa9d623f1cd7 100644 --- a/app/code/Magento/SwaggerWebapiAsync/Model/SchemaType/Async.php +++ b/app/code/Magento/SwaggerWebapiAsync/Model/SchemaType/Async.php @@ -5,7 +5,7 @@ */ namespace Magento\SwaggerWebapiAsync\Model\SchemaType; -use Magento\Swagger\Api\SchemaTypeInterface; +use Magento\Swagger\Api\Data\SchemaTypeInterface; /** * Async swagger schema type. diff --git a/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php b/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php index bac2625fa289e..4c342896af573 100644 --- a/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php +++ b/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php @@ -6,7 +6,7 @@ namespace Magento\SwaggerWebapi\Test\Unit\Model\SchemaType; -use Magento\Swagger\Api\SchemaTypeInterface; +use Magento\Swagger\Api\Data\SchemaTypeInterface; use Magento\SwaggerWebapi\Model\SchemaType\Async; class AsyncTest extends \PHPUnit\Framework\TestCase diff --git a/app/code/Magento/SwaggerWebapiAsync/composer.json b/app/code/Magento/SwaggerWebapiAsync/composer.json index 6ca412c3f717c..acb4494355da7 100644 --- a/app/code/Magento/SwaggerWebapiAsync/composer.json +++ b/app/code/Magento/SwaggerWebapiAsync/composer.json @@ -7,13 +7,14 @@ "require": { "magento/framework": "100.3.*", "magento/module-swagger": "100.3.*", + "magento/module-webapi-async": "100.3.*", "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { "magento/module-config": "100.3.*" }, "type": "magento2-module", - "version": "100.3.0-dev", + "version": "100.0.0", "license": [ "proprietary" ], diff --git a/app/code/Magento/SwaggerWebapiAsync/etc/frontend/di.xml b/app/code/Magento/SwaggerWebapiAsync/etc/frontend/di.xml index f1ee30ba60bb1..6bbcb2d85f564 100644 --- a/app/code/Magento/SwaggerWebapiAsync/etc/frontend/di.xml +++ b/app/code/Magento/SwaggerWebapiAsync/etc/frontend/di.xml @@ -12,12 +12,4 @@ <argument name="code" xsi:type="string">async</argument> </arguments> </type> - - <type name="Magento\Swagger\Block\SchemaTypes"> - <arguments> - <argument name="types" xsi:type="array"> - <item name="async" xsi:type="object">Magento\SwaggerWebapiAsync\Model\SchemaType\Async</item> - </argument> - </arguments> - </type> </config> \ No newline at end of file diff --git a/app/code/Magento/SwaggerWebapiAsync/etc/module.xml b/app/code/Magento/SwaggerWebapiAsync/etc/module.xml index 7e176a552cbf2..5f5333654f2a7 100644 --- a/app/code/Magento/SwaggerWebapiAsync/etc/module.xml +++ b/app/code/Magento/SwaggerWebapiAsync/etc/module.xml @@ -6,9 +6,9 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_SwaggerWebapiAsync" setup_version="0.0.1"> + <module name="Magento_SwaggerWebapiAsync"> <sequence> - <module name="Magento_WebapiAsync" /> + <module name="Magento_Webapi" /> </sequence> </module> </config> diff --git a/app/code/Magento/SwaggerWebapiAsync/view/frontend/layout/swagger_index_index.xml b/app/code/Magento/SwaggerWebapiAsync/view/frontend/layout/swagger_index_index.xml new file mode 100644 index 0000000000000..c64e6f15a09d4 --- /dev/null +++ b/app/code/Magento/SwaggerWebapiAsync/view/frontend/layout/swagger_index_index.xml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <body> + <referenceBlock name="swaggerUiContent"> + <arguments> + <argument name="schema_types" xsi:type="array"> + <item name="async" xsi:type="object">Magento\SwaggerWebapiAsync\Model\SchemaType\Async</item> + </argument> + </arguments> + </referenceBlock> + </body> +</page> diff --git a/app/code/Magento/WebapiAsync/Model/ServiceConfig.php b/app/code/Magento/WebapiAsync/Model/ServiceConfig.php new file mode 100644 index 0000000000000..0fce6c4230cd7 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Model/ServiceConfig.php @@ -0,0 +1,79 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Model; + +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Webapi\Model\Cache\Type\Webapi as WebapiCache; +use Magento\WebapiAsync\Model\ServiceConfig\Converter; +use Magento\WebapiAsync\Model\ServiceConfig\Reader; + +/** + * This class gives access to consolidated web API configuration from <Module_Name>/etc/webapi_async.xml files. + * + * @api + */ +class ServiceConfig +{ + const CACHE_ID = 'webapi_async_config'; + + /** + * @var WebapiCache + */ + private $cache; + + /** + * @var Reader + */ + private $configReader; + + /** + * @var array + */ + private $services; + + /** + * @var SerializerInterface + */ + private $serializer; + + /** + * Initialize dependencies. + * + * @param WebapiCache $cache + * @param Reader $configReader + * @param SerializerInterface|null $serializer + */ + public function __construct( + WebapiCache $cache, + Reader $configReader, + SerializerInterface $serializer = null + ) { + $this->cache = $cache; + $this->configReader = $configReader; + $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class); + } + + /** + * Return services loaded from cache if enabled or from files merged previously + * + * @return array + */ + public function getServices() + { + if (null === $this->services) { + $services = $this->cache->load(self::CACHE_ID); + if ($services && is_string($services)) { + $this->services = $this->serializer->unserialize($services); + } else { + $this->services = $this->configReader->read()[Converter::KEY_SERVICES]; + $this->cache->save($this->serializer->serialize($this->services), self::CACHE_ID); + } + } + return $this->services; + } +} diff --git a/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php b/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php new file mode 100644 index 0000000000000..7081c20406244 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php @@ -0,0 +1,167 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\WebapiAsync\Model\ServiceConfig; + +/** + * Converter of webapi.xml content into array format. + */ +class Converter implements \Magento\Framework\Config\ConverterInterface +{ + /**#@+ + * Array keys for config internal representation. + */ + const KEY_SERVICES = 'services'; + const KEY_METHOD = 'method'; + const KEY_METHODS = 'methods'; + const KEY_SYNCHRONOUS_INVOCATION_ONLY = 'synchronousInvocationOnly'; + /**#@-*/ + + /** + * {@inheritdoc} + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + public function convert($source) + { + $result = [self::KEY_SERVICES => []]; + /** @var \DOMNodeList $services */ + $services = $source->getElementsByTagName('service'); + /** @var \DOMElement $service */ + foreach ($services as $service) { + if (!$this->canConvertXmlNode($service)) { + continue; + } + + $serviceClass = $this->getServiceClass($service); + $serviceMethod = $this->getServiceMethod($service); + + // Define the service method's key if this hasn't yet been defined + $this->initServiceMethodsKey($result, $serviceClass, $serviceMethod); + + $this->mergeSynchronousInvocationMethodsData($service, $result, $serviceClass, $serviceMethod); + } + + return $result; + } + + /** + * Merge service data related to synchronous-only method invocations. + * + * @param \DOMElement $service + * @param array $result + * @param string $serviceClass + * @param string $serviceMethod + */ + private function mergeSynchronousInvocationMethodsData( + \DOMElement $service, + array &$result, + $serviceClass, + $serviceMethod + ) { + $result[self::KEY_SERVICES][$serviceClass][self::KEY_METHODS][$serviceMethod] = array_merge( + $result[self::KEY_SERVICES][$serviceClass][self::KEY_METHODS][$serviceMethod], + [ + self::KEY_SYNCHRONOUS_INVOCATION_ONLY => $this->getSynchronousMethodInvocationOnly($service) + ] + ); + } + + /** + * @param \DOMElement $node + * @return bool + */ + private function canConvertXmlNode(\DOMElement $node) + { + if ($node->nodeType !== XML_ELEMENT_NODE) { + return false; + } + + if ($this->getServiceClass($node) === null) { + return false; + } + + if ($this->getServiceMethod($node) === null) { + return false; + } + + return true; + } + + /** + * Define the methods key against the service. Allows for other types of service information. + * + * @param array $result + * @param string $serviceClass + * @param string $serviceMethod + */ + private function initServiceMethodsKey(array &$result, $serviceClass, $serviceMethod) + { + if (!isset($result[self::KEY_SERVICES][$serviceClass])) { + $result[self::KEY_SERVICES][$serviceClass] = [self::KEY_METHODS => []]; + } + + if (!isset($result[self::KEY_SERVICES][$serviceClass][self::KEY_METHODS][$serviceMethod])) { + $result[self::KEY_SERVICES][$serviceClass][self::KEY_METHODS][$serviceMethod] = []; + } + } + + /** + * @param \DOMElement $service + * @return null|string + */ + private function getServiceClass(\DOMElement $service) + { + $serviceClass = $service->attributes->getNamedItem('class')->nodeValue; + + return mb_strlen((string) $serviceClass) === 0 ? null : $serviceClass; + } + + /** + * @param \DOMElement $service + * @return null|string + */ + private function getServiceMethod(\DOMElement $service) + { + $serviceMethod = $service->attributes->getNamedItem('method')->nodeValue; + + return mb_strlen((string) $serviceMethod) === 0 ? null : $serviceMethod; + } + + /** + * @param \DOMElement $serviceNode + * @return bool + */ + private function getSynchronousMethodInvocationOnly(\DOMElement $serviceNode) + { + $synchronousInvocationOnlyNodes = $serviceNode->getElementsByTagName('synchronousInvocationOnly'); + + // This should be caught by the xsd, but covers some un-expected scenario + if (count($synchronousInvocationOnlyNodes) > 1) { + throw new \InvalidArgumentException( + 'Multiple synchronousInvocationOnly child nodes defined with configuration source' + ); + } + + return $this->isSynchronousInvocationOnlyTrue($synchronousInvocationOnlyNodes->item(0)); + } + + /** + * @param \DOMElement $synchronousInvocationOnlyNode + * @return bool|mixed + */ + private function isSynchronousInvocationOnlyTrue(\DOMElement $synchronousInvocationOnlyNode) + { + if ($synchronousInvocationOnlyNode === null) { + return false; + } + + if (mb_strlen((string) $synchronousInvocationOnlyNode->nodeValue) === 0) { + return true; + } + + return filter_var($synchronousInvocationOnlyNode->nodeValue, FILTER_VALIDATE_BOOLEAN); + } +} diff --git a/app/code/Magento/WebapiAsync/Model/ServiceConfig/Reader.php b/app/code/Magento/WebapiAsync/Model/ServiceConfig/Reader.php new file mode 100644 index 0000000000000..18a3ef2ce9207 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Model/ServiceConfig/Reader.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\WebapiAsync\Model\ServiceConfig; + +/** + * Service config data reader. + */ +class Reader extends \Magento\Framework\Config\Reader\Filesystem +{ + /** + * List of id attributes for merge + * + * @var array + */ + protected $_idAttributes = [ + '/services/service' => ['class', 'method'], + ]; + + /** + * @param \Magento\Framework\Config\FileResolverInterface $fileResolver + * @param Converter $converter + * @param SchemaLocator $schemaLocator + * @param \Magento\Framework\Config\ValidationStateInterface $validationState + * @param string $fileName + * @param array $idAttributes + * @param string $domDocumentClass + * @param string $defaultScope + */ + public function __construct( + \Magento\Framework\Config\FileResolverInterface $fileResolver, + Converter $converter, + SchemaLocator $schemaLocator, + \Magento\Framework\Config\ValidationStateInterface $validationState, + $fileName = 'webapi_async.xml', + $idAttributes = [], + $domDocumentClass = \Magento\Framework\Config\Dom::class, + $defaultScope = 'global' + ) { + parent::__construct( + $fileResolver, + $converter, + $schemaLocator, + $validationState, + $fileName, + $idAttributes, + $domDocumentClass, + $defaultScope + ); + } +} diff --git a/app/code/Magento/WebapiAsync/Model/ServiceConfig/SchemaLocator.php b/app/code/Magento/WebapiAsync/Model/ServiceConfig/SchemaLocator.php new file mode 100644 index 0000000000000..8be5a961673eb --- /dev/null +++ b/app/code/Magento/WebapiAsync/Model/ServiceConfig/SchemaLocator.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\WebapiAsync\Model\ServiceConfig; + +use Magento\Framework\Module\Dir; + +/** + * Web API config schema locator. + */ +class SchemaLocator implements \Magento\Framework\Config\SchemaLocatorInterface +{ + /** + * Path to corresponding XSD file with validation rules for merged config + * + * @var string + */ + protected $_schema = null; + + /** + * Path to corresponding XSD file with validation rules for separate config files + * + * @var string + */ + protected $_perFileSchema = null; + + /** + * @param \Magento\Framework\Module\Dir\Reader $moduleReader + */ + public function __construct(\Magento\Framework\Module\Dir\Reader $moduleReader) + { + $this->_schema = $moduleReader->getModuleDir(Dir::MODULE_ETC_DIR, 'Magento_WebapiAsync') . '/webapi_async.xsd'; + } + + /** + * Get path to merged config schema + * + * @return string|null + */ + public function getSchema() + { + return $this->_schema; + } + + /** + * Get path to per file validation schema + * + * @return string|null + */ + public function getPerFileSchema() + { + return $this->_perFileSchema; + } +} diff --git a/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php b/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php new file mode 100644 index 0000000000000..ed07e25bbb893 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php @@ -0,0 +1,147 @@ +<?php + +namespace Magento\WebapiAsync\Plugin; + +use Magento\Webapi\Model\Config\Converter as WebapiConverter; +use Magento\WebapiAsync\Api\Data\AsyncResponseInterface; +use Magento\WebapiAsync\Controller\Rest\AsynchronousSchemaRequestProcessor; +use Magento\WebapiAsync\Model\ServiceConfig\Converter; + +class ServiceMetadata +{ + /** + * @var \Magento\Webapi\Model\Config + */ + private $webapiConfig; + /** + * @var \Magento\WebapiAsync\Model\ServiceConfig + */ + private $serviceConfig; + /** + * @var AsynchronousSchemaRequestProcessor + */ + private $asynchronousSchemaRequestProcessor; + /** + * @var \Magento\Framework\Webapi\Rest\Request + */ + private $request; + /** + * @var \Magento\Framework\Reflection\TypeProcessor + */ + private $typeProcessor; + + /** + * ServiceMetadata constructor. + * + * @param \Magento\Webapi\Model\Config $webapiConfig + * @param \Magento\WebapiAsync\Model\ServiceConfig $serviceConfig + * @param AsynchronousSchemaRequestProcessor $asynchronousSchemaRequestProcessor + */ + public function __construct( + \Magento\Webapi\Model\Config $webapiConfig, + \Magento\WebapiAsync\Model\ServiceConfig $serviceConfig, + \Magento\Framework\Webapi\Rest\Request $request, + AsynchronousSchemaRequestProcessor $asynchronousSchemaRequestProcessor, + \Magento\Framework\Reflection\TypeProcessor $typeProcessor + ) { + $this->webapiConfig = $webapiConfig; + $this->serviceConfig = $serviceConfig; + $this->request = $request; + $this->asynchronousSchemaRequestProcessor = $asynchronousSchemaRequestProcessor; + $this->typeProcessor = $typeProcessor; + } + + public function afterGetServicesConfig(\Magento\Webapi\Model\ServiceMetadata $subject, $result) + { + if ($this->asynchronousSchemaRequestProcessor->canProcess($this->request)) { + $synchronousOnlyServiceMethods = $this->getSynchronousOnlyServiceMethods($subject); + // Replace all results with the async response schema + foreach ($result as $serviceName => $serviceData) { + // Check all of the methods on the service + foreach ($serviceData[WebapiConverter::KEY_METHODS] as $methodName => $methodData) { + // Exclude service methods that are marked as synchronous only + if (!$this->isServiceMethodSynchronousOnly( + $serviceName, + $methodName, + $synchronousOnlyServiceMethods + )) { + $result[$serviceName][WebapiConverter::KEY_METHODS][$methodName] = array_merge( + $result[$serviceName][WebapiConverter::KEY_METHODS][$methodName], + ['interface']['out']['parameters']['result'] = [ + 'type' => $this->typeProcessor->register(AsyncResponseInterface::class), + 'documentation' => 'Returns a 202 Accepted Response when successfully queued.', + 'required' => true, + ] + ); + } + } + } + } + } + + /** + * @param $serviceName + * @param $methodName + * @param array $synchronousOnlyServiceMethods + * @return bool + */ + private function isServiceMethodSynchronousOnly($serviceName, $methodName, array $synchronousOnlyServiceMethods) + { + return isset($synchronousOnlyServiceMethods[$serviceName][$methodName]); + } + + /** + * @return array + */ + private function getServiceVersions() + { + $services = $this->webapiConfig->getServices(); + $serviceVersionData = array_values($services[WebapiConverter::KEY_SERVICES]); + + return array_keys($serviceVersionData); + } + + /** + * @param \Magento\Webapi\Model\ServiceMetadata $serviceMetadata + * @return array + */ + private function getSynchronousOnlyServiceMethods(\Magento\Webapi\Model\ServiceMetadata $serviceMetadata) + { + $synchronousOnlyServiceMethods = []; + foreach ($this->serviceConfig->getServices() as $service => $serviceData) { + if (!isset($serviceData[Converter::KEY_METHODS])) { + continue; + } + + foreach ($serviceData[Converter::KEY_METHODS] as $method => $methodData) { + if ($this->isMethodDataSynchronousOnly($methodData)) { + foreach ($this->getServiceVersions() as $serviceVersion) { + $serviceName = $serviceMetadata->getServiceName($service, $serviceVersion); + if (!array_key_exists($serviceName, $synchronousOnlyServiceMethods)) { + $synchronousOnlyServiceMethods[$serviceName] = []; + } + + $synchronousOnlyServiceMethods[$serviceName][$method] = true; + } + } + } + } + + return $synchronousOnlyServiceMethods; + } + + /** + * Check if a method on the given service is defined as synchronous only. + * + * @param array $methodData + * @return bool + */ + private function isMethodDataSynchronousOnly(array $methodData) + { + if (!isset($methodData[Converter::KEY_SYNCHRONOUS_INVOCATION_ONLY])) { + return false; + } + + return $methodData[Converter::KEY_SYNCHRONOUS_INVOCATION_ONLY]; + } +} diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ConverterTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ConverterTest.php new file mode 100644 index 0000000000000..698dba67dfd44 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ConverterTest.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\WebapiAsync\Test\Unit\Model\ServiceConfig; + +class ConverterTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\WebapiAsync\Model\ServiceConfig\Converter + */ + protected $_model; + + protected function setUp() + { + $this->_model = new \Magento\WebapiAsync\Model\ServiceConfig\Converter(); + } + + /** + * @covers \Magento\WebapiAsync\Model\ServiceConfig\Converter::convert() + */ + public function testConvert() + { + $inputData = new \DOMDocument(); + $inputData->load(__DIR__ . '/_files/Converter/webapi_async.xml'); + $expectedResult = require __DIR__ . '/_files/Converter/webapi_async.php'; + $this->assertEquals($expectedResult, $this->_model->convert($inputData)); + } +} diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ReaderTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ReaderTest.php new file mode 100644 index 0000000000000..a7251d169d506 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ReaderTest.php @@ -0,0 +1,58 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\WebapiAsync\Test\Unit\Model\ServiceConfig; + +use Magento\Framework\Config\FileResolverInterface; +use Magento\WebapiAsync\Model\ServiceConfig\Converter; +use Magento\WebapiAsync\Model\ServiceConfig\Reader; + +class ReaderTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var Reader + */ + private $reader; + + /** + * @var FileResolverInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $fileResolver; + + public function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->fileResolver = $this + ->getMockForAbstractClass(\Magento\Framework\Config\FileResolverInterface::class); + + $this->reader = $objectManager->getObject( + Reader::class, + [ + 'fileResolver' => $this->fileResolver, + 'converter' => $objectManager->getObject(Converter::class), + ] + ); + } + + /** + * @covers \Magento\WebapiAsync\Model\ServiceConfig\Reader::read() + */ + public function testReader() + { + $this->fileResolver->expects($this->once()) + ->method('get') + ->with('webapi_async.xml', 'global')->willReturn( + [ + file_get_contents(__DIR__ . '/_files/Reader/webapi_async_1.xml'), + file_get_contents(__DIR__ . '/_files/Reader/webapi_async_2.xml'), + ] + ); + + $mergedConfiguration = include __DIR__ . '/_files/Reader/webapi_async.php'; + $readConfiguration = $this->reader->read(); + + $this->assertEquals($mergedConfiguration, $readConfiguration); + } +} diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/SchemaLocatorTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/SchemaLocatorTest.php new file mode 100644 index 0000000000000..2d4287adcdfaf --- /dev/null +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/SchemaLocatorTest.php @@ -0,0 +1,49 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\WebapiAsync\Test\Unit\Model\ServiceConfig; + +class SchemaLocatorTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $_moduleReaderMock; + + /** + * @var \Magento\WebapiAsync\Model\ServiceConfig\SchemaLocator + */ + protected $_model; + + protected function setUp() + { + $this->_moduleReaderMock = $this->createPartialMock( + \Magento\Framework\Module\Dir\Reader::class, + ['getModuleDir'] + ); + $this->_moduleReaderMock->expects( + $this->any() + )->method( + 'getModuleDir' + )->with( + 'etc', + 'Magento_WebapiAsync' + )->will( + $this->returnValue('schema_dir') + ); + + $this->_model = new \Magento\WebapiAsync\Model\ServiceConfig\SchemaLocator($this->_moduleReaderMock); + } + + public function testGetSchema() + { + $this->assertEquals('schema_dir/webapi_async.xsd', $this->_model->getSchema()); + } + + public function testGetPerFileSchema() + { + $this->assertEquals(null, $this->_model->getPerFileSchema()); + } +} diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.php b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.php new file mode 100644 index 0000000000000..44c6f006306fc --- /dev/null +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.php @@ -0,0 +1,22 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +return [ + 'services' => [ + \Magento\Customer\Api\CustomerRepositoryInterface::class => [ + 'methods' => [ + 'getById' => [ + 'synchronousInvocationOnly' => true, + ], + 'save' => [ + 'synchronousInvocationOnly' => true, + ], + 'get' => [ + 'synchronousInvocationOnly' => false, + ], + ], + ], + ], +]; diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.xml b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.xml new file mode 100644 index 0000000000000..e4ba6da62339c --- /dev/null +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.xml @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_WebapiAsync:etc/webapi_async.xsd"> + <service class="Magento\Customer\Api\CustomerRepositoryInterface" method="getById"> + <synchronousInvocationOnly>true</synchronousInvocationOnly> + </service> + + <service class="Magento\Customer\Api\CustomerRepositoryInterface" method="save"> + <synchronousInvocationOnly /> + </service> + + <service class="Magento\Customer\Api\CustomerRepositoryInterface" method="get" /> +</services> diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async.php b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async.php new file mode 100644 index 0000000000000..44c6f006306fc --- /dev/null +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async.php @@ -0,0 +1,22 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +return [ + 'services' => [ + \Magento\Customer\Api\CustomerRepositoryInterface::class => [ + 'methods' => [ + 'getById' => [ + 'synchronousInvocationOnly' => true, + ], + 'save' => [ + 'synchronousInvocationOnly' => true, + ], + 'get' => [ + 'synchronousInvocationOnly' => false, + ], + ], + ], + ], +]; diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_1.xml b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_1.xml new file mode 100644 index 0000000000000..7f816f510ddb6 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_1.xml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_WebapiAsync:etc/webapi_async.xsd"> + <service class="Magento\Customer\Api\CustomerRepositoryInterface" method="getById"> + <synchronousInvocationOnly>true</synchronousInvocationOnly> + </service> + + <service class="Magento\Customer\Api\CustomerRepositoryInterface" method="save"> + <synchronousInvocationOnly /> + </service> + +</services> diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_2.xml b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_2.xml new file mode 100644 index 0000000000000..7a5bebd8fe566 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_2.xml @@ -0,0 +1,12 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_WebapiAsync:etc/webapi_async.xsd"> + <service class="Magento\Customer\Api\CustomerRepositoryInterface" method="get" /> + +</services> diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfigTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfigTest.php new file mode 100644 index 0000000000000..c21c5181ae208 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfigTest.php @@ -0,0 +1,96 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Webapi\Test\Unit\Model; + +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Webapi\Model\Cache\Type\Webapi; +use Magento\Webapi\Model\Config; +use Magento\Webapi\Model\Config\Reader; + +class ServiceConfigTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var Config + */ + private $config; + + /** + * @var Webapi|\PHPUnit_Framework_MockObject_MockObject + */ + private $webapiCacheMock; + + /** + * @var Reader|\PHPUnit_Framework_MockObject_MockObject + */ + private $configReaderMock; + + /** + * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $serializerMock; + + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->webapiCacheMock = $this->createMock(\Magento\Webapi\Model\Cache\Type\Webapi::class); + $this->configReaderMock = $this->createMock(\Magento\Webapi\Model\Config\Reader::class); + $this->serializerMock = $this->createMock(SerializerInterface::class); + + $this->config = $objectManager->getObject( + Config::class, + [ + 'cache' => $this->webapiCacheMock, + 'configReader' => $this->configReaderMock, + 'serializer' => $this->serializerMock + ] + ); + } + + public function testGetServices() + { + $data = ['foo' => 'bar']; + $serializedData = 'serialized data'; + $this->webapiCacheMock->expects($this->once()) + ->method('load') + ->with(Config::CACHE_ID) + ->willReturn($serializedData); + $this->serializerMock->expects($this->once()) + ->method('unserialize') + ->with($serializedData) + ->willReturn($data); + $this->config->getServices(); + $this->assertEquals($data, $this->config->getServices()); + } + + public function testGetServicesNoCache() + { + $data = ['foo' => 'bar']; + $serializedData = 'serialized data'; + $this->webapiCacheMock->expects($this->once()) + ->method('load') + ->with(Config::CACHE_ID) + ->willReturn(false); + $this->serializerMock->expects($this->never()) + ->method('unserialize'); + $this->configReaderMock->expects($this->once()) + ->method('read') + ->willReturn($data); + $this->serializerMock->expects($this->once()) + ->method('serialize') + ->with($data) + ->willReturn($serializedData); + $this->webapiCacheMock->expects($this->once()) + ->method('save') + ->with( + $serializedData, + Config::CACHE_ID + ); + + $this->config->getServices(); + $this->assertEquals($data, $this->config->getServices()); + } +} diff --git a/app/code/Magento/WebapiAsync/etc/frontend/di.xml b/app/code/Magento/WebapiAsync/etc/frontend/di.xml new file mode 100644 index 0000000000000..393bc39d12479 --- /dev/null +++ b/app/code/Magento/WebapiAsync/etc/frontend/di.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <type name="Magento\Webapi\Model\ServiceMetadata"> + <plugin name="webapiServiceMetadataAsync" type="Magento\WebapiAsync\Plugin\ServiceMetadata" /> + </type> + +</config> diff --git a/app/code/Magento/WebapiAsync/etc/webapi_async.xsd b/app/code/Magento/WebapiAsync/etc/webapi_async.xsd new file mode 100644 index 0000000000000..468ebd96553b6 --- /dev/null +++ b/app/code/Magento/WebapiAsync/etc/webapi_async.xsd @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Structure description for webapi_async.xml configuration files. + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:element name="services" type="servicesType"/> + + <xs:complexType name="serviceType"> + <xs:sequence> + <xs:element name="synchronousInvocationOnly" type="xs:boolean" minOccurs="0"/> + </xs:sequence> + <xs:attribute name="class" type="xs:string" use="required"/> + <xs:attribute name="method" type="xs:string" use="required"/> + </xs:complexType> + + <xs:complexType name="servicesType"> + <xs:sequence> + <xs:element name="service" type="servicesType" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + +</xs:schema> From 2d1749adc7975447acab04a45789bf5b18063126 Mon Sep 17 00:00:00 2001 From: Carey Sizer <carey@balanceinternet.com.au> Date: Thu, 22 Mar 2018 20:57:12 +1300 Subject: [PATCH 174/668] Implemented integration tests and completed basic integration with AsynchronousSchemaRequestProcessor --- .../WebapiAsync/Model/ServiceConfig.php | 2 +- .../WebapiAsync/Plugin/ServiceMetadata.php | 60 +++++++++++--- app/code/Magento/WebapiAsync/etc/di.xml | 4 + .../Magento/WebapiAsync/etc/frontend/di.xml | 14 ---- ...AsynchronousSchemaRequestProcessorMock.php | 18 +++++ .../Plugin/ServiceMetadataTest.php | 78 +++++++++++++++++++ 6 files changed, 152 insertions(+), 24 deletions(-) delete mode 100644 app/code/Magento/WebapiAsync/etc/frontend/di.xml create mode 100644 dev/tests/integration/testsuite/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessorMock.php create mode 100644 dev/tests/integration/testsuite/Magento/WebapiAsync/Plugin/ServiceMetadataTest.php diff --git a/app/code/Magento/WebapiAsync/Model/ServiceConfig.php b/app/code/Magento/WebapiAsync/Model/ServiceConfig.php index 0fce6c4230cd7..e44c5282bf1a4 100644 --- a/app/code/Magento/WebapiAsync/Model/ServiceConfig.php +++ b/app/code/Magento/WebapiAsync/Model/ServiceConfig.php @@ -70,7 +70,7 @@ public function getServices() if ($services && is_string($services)) { $this->services = $this->serializer->unserialize($services); } else { - $this->services = $this->configReader->read()[Converter::KEY_SERVICES]; + $this->services = $this->configReader->read()[Converter::KEY_SERVICES] ?? []; $this->cache->save($this->serializer->serialize($this->services), self::CACHE_ID); } } diff --git a/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php b/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php index ed07e25bbb893..a64300b5e52b8 100644 --- a/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php +++ b/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php @@ -29,6 +29,10 @@ class ServiceMetadata * @var \Magento\Framework\Reflection\TypeProcessor */ private $typeProcessor; + /** + * @var array + */ + private $responseDefinitionReplacement; /** * ServiceMetadata constructor. @@ -51,7 +55,12 @@ public function __construct( $this->typeProcessor = $typeProcessor; } - public function afterGetServicesConfig(\Magento\Webapi\Model\ServiceMetadata $subject, $result) + /** + * @param \Magento\Webapi\Model\ServiceMetadata $subject + * @param array $result + * @return array + */ + public function afterGetServicesConfig(\Magento\Webapi\Model\ServiceMetadata $subject, array $result) { if ($this->asynchronousSchemaRequestProcessor->canProcess($this->request)) { $synchronousOnlyServiceMethods = $this->getSynchronousOnlyServiceMethods($subject); @@ -65,18 +74,13 @@ public function afterGetServicesConfig(\Magento\Webapi\Model\ServiceMetadata $su $methodName, $synchronousOnlyServiceMethods )) { - $result[$serviceName][WebapiConverter::KEY_METHODS][$methodName] = array_merge( - $result[$serviceName][WebapiConverter::KEY_METHODS][$methodName], - ['interface']['out']['parameters']['result'] = [ - 'type' => $this->typeProcessor->register(AsyncResponseInterface::class), - 'documentation' => 'Returns a 202 Accepted Response when successfully queued.', - 'required' => true, - ] - ); + $result = $this->replaceResponseDefinition($result, $serviceName, $methodName); } } } } + + return $result; } /** @@ -130,6 +134,24 @@ private function getSynchronousOnlyServiceMethods(\Magento\Webapi\Model\ServiceM return $synchronousOnlyServiceMethods; } + /** + * @param array $result + * @param $serviceName + * @param $methodName + * @return array + */ + private function replaceResponseDefinition(array $result, $serviceName, $methodName) + { + if (!isset($result[$serviceName][WebapiConverter::KEY_METHODS][$methodName]['interface']['out'])) { + return $result; + } + + $replacement = $this->getResponseDefinitionReplacement(); + $result[$serviceName][WebapiConverter::KEY_METHODS][$methodName]['interface']['out'] = $replacement; + + return $result; + } + /** * Check if a method on the given service is defined as synchronous only. * @@ -144,4 +166,24 @@ private function isMethodDataSynchronousOnly(array $methodData) return $methodData[Converter::KEY_SYNCHRONOUS_INVOCATION_ONLY]; } + + /** + * @return array + */ + private function getResponseDefinitionReplacement() + { + if ($this->responseDefinitionReplacement === null) { + $this->responseDefinitionReplacement = [ + 'parameters' => [ + 'result' => [ + 'type' => $this->typeProcessor->register(AsyncResponseInterface::class), + 'documentation' => 'Returns a 202 Accepted Response when successfully queued.', + 'required' => true, + ] + ] + ]; + } + + return $this->responseDefinitionReplacement; + } } diff --git a/app/code/Magento/WebapiAsync/etc/di.xml b/app/code/Magento/WebapiAsync/etc/di.xml index 3903f1e3487f3..d2f984fae1cf8 100755 --- a/app/code/Magento/WebapiAsync/etc/di.xml +++ b/app/code/Magento/WebapiAsync/etc/di.xml @@ -42,4 +42,8 @@ </arguments> </type> + <type name="Magento\Webapi\Model\ServiceMetadata"> + <plugin name="webapiServiceMetadataAsync" type="Magento\WebapiAsync\Plugin\ServiceMetadata" /> + </type> + </config> diff --git a/app/code/Magento/WebapiAsync/etc/frontend/di.xml b/app/code/Magento/WebapiAsync/etc/frontend/di.xml deleted file mode 100644 index 393bc39d12479..0000000000000 --- a/app/code/Magento/WebapiAsync/etc/frontend/di.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <type name="Magento\Webapi\Model\ServiceMetadata"> - <plugin name="webapiServiceMetadataAsync" type="Magento\WebapiAsync\Plugin\ServiceMetadata" /> - </type> - -</config> diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessorMock.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessorMock.php new file mode 100644 index 0000000000000..f60e57fce8b0c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessorMock.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Controller\Rest; + +class AsynchronousSchemaRequestProcessorMock extends AsynchronousSchemaRequestProcessor +{ + /** + * {@inheritdoc} + */ + public function canProcess(\Magento\Framework\Webapi\Rest\Request $request) + { + return true; + } +} diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Plugin/ServiceMetadataTest.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Plugin/ServiceMetadataTest.php new file mode 100644 index 0000000000000..d7095e23122bb --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Plugin/ServiceMetadataTest.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Webapi\Plugin; + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Customer\Api\AccountManagementInterface; +use Magento\Webapi\Model\ServiceMetadata; +use Magento\WebapiAsync\Controller\Rest\AsynchronousSchemaRequestProcessor; +use Magento\WebapiAsync\Controller\Rest\AsynchronousSchemaRequestProcessorMock; + +class ServiceMetadataTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ServiceMetadata + */ + private $serviceMetadata; + + protected function setUp() + { + $objectManager = Bootstrap::getObjectManager(); + $objectManager->configure([ + 'preferences' => [ + AsynchronousSchemaRequestProcessor::class => AsynchronousSchemaRequestProcessorMock::class + ] + ]); + + $this->serviceMetadata = $objectManager->create(ServiceMetadata::class); + } + + public function testGetServiceMetadata() + { + $expected = [ + 'methods' => [ + 'activate' => [ + 'method' => 'activate', + 'inputRequired' => false, + 'isSecure' => false, + 'resources' => [ + 'Magento_Customer::manage' + ], + 'documentation' => 'Activate a customer account using a key that was sent in a confirmation email.', + 'interface' => [ + 'in' => [ + 'parameters' => [ + 'email' => [ + 'type' => 'string', + 'required' => true, + 'documentation' => null + ], + 'confirmationKey' => [ + 'type' => 'string', + 'required' => true, + 'documentation' => null + ] + ] + ], + 'out' => [ + 'parameters' => [ + 'result' => [ + 'type' => 'WebapiAsyncDataAsyncResponseInterface', + 'required' => true, + 'documentation' => 'Returns a 202 Accepted Response when successfully queued.' + ] + ] + ] + ] + ] + ], + 'class' => AccountManagementInterface::class, + 'description' => 'Interface for managing customers accounts.', + ]; + $actual = $this->serviceMetadata->getServiceMetadata('customerAccountManagementV1'); + $this->assertEquals(array_replace_recursive($actual, $expected), $actual); + } +} From 918049cbfef4810d3ed1b8b9c1c401ff64ad2383 Mon Sep 17 00:00:00 2001 From: Carey Sizer <carey@balanceinternet.com.au> Date: Fri, 23 Mar 2018 09:48:52 +1300 Subject: [PATCH 175/668] Added HTTP 202 Response code for async schema responses --- .../Magento/Webapi/Model/Rest/Swagger/Generator.php | 12 ++++++++++-- .../Magento/WebapiAsync/Plugin/ServiceMetadata.php | 8 +++++++- .../WebapiAsync/Plugin/ServiceMetadataTest.php | 8 +++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Webapi/Model/Rest/Swagger/Generator.php b/app/code/Magento/Webapi/Model/Rest/Swagger/Generator.php index 6609040b040d0..aeeb256b99aba 100644 --- a/app/code/Magento/Webapi/Model/Rest/Swagger/Generator.php +++ b/app/code/Magento/Webapi/Model/Rest/Swagger/Generator.php @@ -862,9 +862,17 @@ private function generateMethodSuccessResponse($parameters, $responses) if (isset($parameters['result']['type'])) { $schema = $this->getObjectSchema($parameters['result']['type'], $description); } - $responses['200']['description'] = '200 Success.'; + + // Some methods may have a non-standard HTTP success code. + $specificResponseData = $parameters['result']['response_codes']['success'] ?? []; + // Default HTTP success code to 200 if nothing has been supplied. + $responseCode = $specificResponseData['code'] ?? '200'; + // Default HTTP response status to 200 Success if nothing has been supplied. + $responseDescription = $specificResponseData['description'] ?? '200 Success.'; + + $responses[$responseCode]['description'] = $responseDescription; if (!empty($schema)) { - $responses['200']['schema'] = $schema; + $responses[$responseCode]['schema'] = $schema; } } return $responses; diff --git a/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php b/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php index a64300b5e52b8..3ad55ab32d769 100644 --- a/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php +++ b/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php @@ -177,8 +177,14 @@ private function getResponseDefinitionReplacement() 'parameters' => [ 'result' => [ 'type' => $this->typeProcessor->register(AsyncResponseInterface::class), - 'documentation' => 'Returns a 202 Accepted Response when successfully queued.', + 'documentation' => 'Returns response information for the asynchronous request.', 'required' => true, + 'response_codes' => [ + 'success' => [ + 'code' => '202', + 'description' => '202 Accepted.' + ] + ] ] ] ]; diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Plugin/ServiceMetadataTest.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Plugin/ServiceMetadataTest.php index d7095e23122bb..db746964fedee 100644 --- a/dev/tests/integration/testsuite/Magento/WebapiAsync/Plugin/ServiceMetadataTest.php +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Plugin/ServiceMetadataTest.php @@ -62,7 +62,13 @@ public function testGetServiceMetadata() 'result' => [ 'type' => 'WebapiAsyncDataAsyncResponseInterface', 'required' => true, - 'documentation' => 'Returns a 202 Accepted Response when successfully queued.' + 'documentation' => 'Returns response information for the asynchronous request.', + 'response_codes' => [ + 'success' => [ + 'code' => '202', + 'description' => '202 Accepted.' + ] + ] ] ] ] From 994f8b2251e35e4f4b978707f5e2e9b716179d9b Mon Sep 17 00:00:00 2001 From: Carey Sizer <carey@balanceinternet.com.au> Date: Fri, 23 Mar 2018 11:37:37 +1300 Subject: [PATCH 176/668] Added integration test for Swagger Generator to test async output is correct --- .../WebapiAsync/Model/AuthorizationMock.php | 20 +++++ .../Model/Rest/Swagger/GeneratorTest.php | 74 +++++++++++++++++++ .../Plugin/ServiceMetadataTest.php | 2 +- 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 dev/tests/integration/testsuite/Magento/WebapiAsync/Model/AuthorizationMock.php create mode 100644 dev/tests/integration/testsuite/Magento/WebapiAsync/Model/Rest/Swagger/GeneratorTest.php diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/AuthorizationMock.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/AuthorizationMock.php new file mode 100644 index 0000000000000..83aba3afef240 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/AuthorizationMock.php @@ -0,0 +1,20 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\WebapiAsync\Model; + +use Magento\Framework\Webapi\Authorization; + +class AuthorizationMock extends Authorization +{ + /** + * @param string[] $aclResources + * @return bool + */ + public function isAllowed($aclResources) + { + return true; + } +} \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/Rest/Swagger/GeneratorTest.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/Rest/Swagger/GeneratorTest.php new file mode 100644 index 0000000000000..377c5c2d8b3ab --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/Rest/Swagger/GeneratorTest.php @@ -0,0 +1,74 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\WebapiAsync\Model\Rest\Swagger; + +use Magento\Framework\Webapi\Authorization; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Webapi\Model\Rest\Swagger\Generator; +use Magento\Webapi\Model\ServiceMetadata; +use Magento\WebapiAsync\Controller\Rest\AsynchronousSchemaRequestProcessor; +use Magento\WebapiAsync\Controller\Rest\AsynchronousSchemaRequestProcessorMock; +use Magento\WebapiAsync\Model\AuthorizationMock; + +class GeneratorTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var Generator + */ + private $generator; + + /** + * @var ServiceMetadata + */ + private $serviceMetadata; + + protected function setUp() + { + $objectManager = Bootstrap::getObjectManager(); + $objectManager->configure([ + 'preferences' => [ + Authorization::class => AuthorizationMock::class, + AsynchronousSchemaRequestProcessor::class => AsynchronousSchemaRequestProcessorMock::class + ] + ]); + + $this->generator = $objectManager->create(Generator::class); + $this->serviceMetadata = $objectManager->create(ServiceMetadata::class); + } + + public function testGenerateAsync() + { + $schema = json_decode( + $this->generator->generate( + ['customerAccountManagementV1'], + 'https', + 'localhost', + '/async/schema/V1?services=customerAccountManagementV1' + ), + true + ); + + // Ensure that the correct HTTP response has been described in the schema. + $this->assertArrayHasKey( + '202', + $schema['paths']['/V1/customers']['post']['responses'] + ); + + $this->assertArrayNotHasKey( + '200', + $schema['paths']['/V1/customers']['post']['responses'] + ); + + // Ensure that the response type has been replaced with the async version. + $this->assertEquals( + '#/definitions/webapi-async-data-async-response-interface', + $schema['paths']['/V1/customers']['post']['responses']['202']['schema']['$ref'] + ); + + // Ensure that the base path output correctly + $this->assertEquals('/async', $schema['basePath']); + } +} diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Plugin/ServiceMetadataTest.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Plugin/ServiceMetadataTest.php index db746964fedee..bddd05034a8a4 100644 --- a/dev/tests/integration/testsuite/Magento/WebapiAsync/Plugin/ServiceMetadataTest.php +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Plugin/ServiceMetadataTest.php @@ -3,7 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Webapi\Plugin; +namespace Magento\WebapiAsync\Plugin; use Magento\TestFramework\Helper\Bootstrap; use Magento\Customer\Api\AccountManagementInterface; From 5827026caeb2d184e4695a26262312c2377668f7 Mon Sep 17 00:00:00 2001 From: Carey Sizer <carey@balanceinternet.com.au> Date: Fri, 23 Mar 2018 11:44:30 +1300 Subject: [PATCH 177/668] Coding Style fixes --- app/code/Magento/Swagger/etc/module.xml | 2 +- .../Magento/WebapiAsync/Model/ServiceConfig.php | 7 +++---- .../WebapiAsync/Model/ServiceConfig/Converter.php | 9 +-------- .../Model/ServiceConfig/SchemaLocator.php | 12 ++++++------ .../Unit/Model/ServiceConfig/ConverterTest.php | 6 +++--- .../Unit/Model/ServiceConfig/SchemaLocatorTest.php | 14 +++++++------- .../WebapiAsync/Model/AuthorizationMock.php | 2 +- 7 files changed, 22 insertions(+), 30 deletions(-) diff --git a/app/code/Magento/Swagger/etc/module.xml b/app/code/Magento/Swagger/etc/module.xml index 9a136e619e12b..ecc3fd507e9af 100644 --- a/app/code/Magento/Swagger/etc/module.xml +++ b/app/code/Magento/Swagger/etc/module.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Magento_Swagger"> <sequence> - <module name="Magento_SwaggerWebapi" /> + <module name="Magento_Webapi" /> </sequence> </module> </config> diff --git a/app/code/Magento/WebapiAsync/Model/ServiceConfig.php b/app/code/Magento/WebapiAsync/Model/ServiceConfig.php index e44c5282bf1a4..47b2cca13d690 100644 --- a/app/code/Magento/WebapiAsync/Model/ServiceConfig.php +++ b/app/code/Magento/WebapiAsync/Model/ServiceConfig.php @@ -6,7 +6,6 @@ namespace Magento\WebapiAsync\Model; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Serialize\SerializerInterface; use Magento\Webapi\Model\Cache\Type\Webapi as WebapiCache; use Magento\WebapiAsync\Model\ServiceConfig\Converter; @@ -46,16 +45,16 @@ class ServiceConfig * * @param WebapiCache $cache * @param Reader $configReader - * @param SerializerInterface|null $serializer + * @param SerializerInterface $serializer */ public function __construct( WebapiCache $cache, Reader $configReader, - SerializerInterface $serializer = null + SerializerInterface $serializer ) { $this->cache = $cache; $this->configReader = $configReader; - $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class); + $this->serializer = $serializer; } /** diff --git a/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php b/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php index 7081c20406244..1b2ccfdcbc75a 100644 --- a/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php +++ b/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php @@ -6,7 +6,7 @@ namespace Magento\WebapiAsync\Model\ServiceConfig; /** - * Converter of webapi.xml content into array format. + * Converter of webapi_async.xml content into array format. */ class Converter implements \Magento\Framework\Config\ConverterInterface { @@ -138,13 +138,6 @@ private function getSynchronousMethodInvocationOnly(\DOMElement $serviceNode) { $synchronousInvocationOnlyNodes = $serviceNode->getElementsByTagName('synchronousInvocationOnly'); - // This should be caught by the xsd, but covers some un-expected scenario - if (count($synchronousInvocationOnlyNodes) > 1) { - throw new \InvalidArgumentException( - 'Multiple synchronousInvocationOnly child nodes defined with configuration source' - ); - } - return $this->isSynchronousInvocationOnlyTrue($synchronousInvocationOnlyNodes->item(0)); } diff --git a/app/code/Magento/WebapiAsync/Model/ServiceConfig/SchemaLocator.php b/app/code/Magento/WebapiAsync/Model/ServiceConfig/SchemaLocator.php index 8be5a961673eb..a8d9e8a73a93f 100644 --- a/app/code/Magento/WebapiAsync/Model/ServiceConfig/SchemaLocator.php +++ b/app/code/Magento/WebapiAsync/Model/ServiceConfig/SchemaLocator.php @@ -8,7 +8,7 @@ use Magento\Framework\Module\Dir; /** - * Web API config schema locator. + * Web API Async config schema locator. */ class SchemaLocator implements \Magento\Framework\Config\SchemaLocatorInterface { @@ -17,21 +17,21 @@ class SchemaLocator implements \Magento\Framework\Config\SchemaLocatorInterface * * @var string */ - protected $_schema = null; + private $schema = null; /** * Path to corresponding XSD file with validation rules for separate config files * * @var string */ - protected $_perFileSchema = null; + private $perFileSchema = null; /** * @param \Magento\Framework\Module\Dir\Reader $moduleReader */ public function __construct(\Magento\Framework\Module\Dir\Reader $moduleReader) { - $this->_schema = $moduleReader->getModuleDir(Dir::MODULE_ETC_DIR, 'Magento_WebapiAsync') . '/webapi_async.xsd'; + $this->schema = $moduleReader->getModuleDir(Dir::MODULE_ETC_DIR, 'Magento_WebapiAsync') . '/webapi_async.xsd'; } /** @@ -41,7 +41,7 @@ public function __construct(\Magento\Framework\Module\Dir\Reader $moduleReader) */ public function getSchema() { - return $this->_schema; + return $this->schema; } /** @@ -51,6 +51,6 @@ public function getSchema() */ public function getPerFileSchema() { - return $this->_perFileSchema; + return $this->perFileSchema; } } diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ConverterTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ConverterTest.php index 698dba67dfd44..7ef2043525479 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ConverterTest.php +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ConverterTest.php @@ -10,11 +10,11 @@ class ConverterTest extends \PHPUnit\Framework\TestCase /** * @var \Magento\WebapiAsync\Model\ServiceConfig\Converter */ - protected $_model; + private $model; protected function setUp() { - $this->_model = new \Magento\WebapiAsync\Model\ServiceConfig\Converter(); + $this->model = new \Magento\WebapiAsync\Model\ServiceConfig\Converter(); } /** @@ -25,6 +25,6 @@ public function testConvert() $inputData = new \DOMDocument(); $inputData->load(__DIR__ . '/_files/Converter/webapi_async.xml'); $expectedResult = require __DIR__ . '/_files/Converter/webapi_async.php'; - $this->assertEquals($expectedResult, $this->_model->convert($inputData)); + $this->assertEquals($expectedResult, $this->model->convert($inputData)); } } diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/SchemaLocatorTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/SchemaLocatorTest.php index 2d4287adcdfaf..ccec768a36cdf 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/SchemaLocatorTest.php +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/SchemaLocatorTest.php @@ -10,20 +10,20 @@ class SchemaLocatorTest extends \PHPUnit\Framework\TestCase /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_moduleReaderMock; + private $moduleReaderMock; /** * @var \Magento\WebapiAsync\Model\ServiceConfig\SchemaLocator */ - protected $_model; + private $model; protected function setUp() { - $this->_moduleReaderMock = $this->createPartialMock( + $this->moduleReaderMock = $this->createPartialMock( \Magento\Framework\Module\Dir\Reader::class, ['getModuleDir'] ); - $this->_moduleReaderMock->expects( + $this->moduleReaderMock->expects( $this->any() )->method( 'getModuleDir' @@ -34,16 +34,16 @@ protected function setUp() $this->returnValue('schema_dir') ); - $this->_model = new \Magento\WebapiAsync\Model\ServiceConfig\SchemaLocator($this->_moduleReaderMock); + $this->model = new \Magento\WebapiAsync\Model\ServiceConfig\SchemaLocator($this->moduleReaderMock); } public function testGetSchema() { - $this->assertEquals('schema_dir/webapi_async.xsd', $this->_model->getSchema()); + $this->assertEquals('schema_dir/webapi_async.xsd', $this->model->getSchema()); } public function testGetPerFileSchema() { - $this->assertEquals(null, $this->_model->getPerFileSchema()); + $this->assertEquals(null, $this->model->getPerFileSchema()); } } diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/AuthorizationMock.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/AuthorizationMock.php index 83aba3afef240..bb0b7f2fbc964 100644 --- a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/AuthorizationMock.php +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/AuthorizationMock.php @@ -17,4 +17,4 @@ public function isAllowed($aclResources) { return true; } -} \ No newline at end of file +} From 8f0fba87c219c1a2ac3ef918d1da1a6956cb5c81 Mon Sep 17 00:00:00 2001 From: Carey Sizer <carey@balanceinternet.com.au> Date: Fri, 23 Mar 2018 16:01:01 +1300 Subject: [PATCH 178/668] Fixed issue with Swagger schema showing asynchronous responses for GET requests --- .../WebapiAsync/Plugin/ServiceMetadata.php | 85 ++++++++++++++++--- .../Model/Rest/Swagger/GeneratorTest.php | 6 ++ 2 files changed, 80 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php b/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php index 3ad55ab32d769..11a1d3ab4cf54 100644 --- a/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php +++ b/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php @@ -1,4 +1,8 @@ <?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\WebapiAsync\Plugin; @@ -33,6 +37,12 @@ class ServiceMetadata * @var array */ private $responseDefinitionReplacement; + /** + * @var array + */ + private $synchronousOnlyHttpMethods = [ + 'GET' + ]; /** * ServiceMetadata constructor. @@ -95,17 +105,19 @@ private function isServiceMethodSynchronousOnly($serviceName, $methodName, array } /** + * @param string $serviceName * @return array */ - private function getServiceVersions() + private function getServiceVersions(string $serviceName) { $services = $this->webapiConfig->getServices(); - $serviceVersionData = array_values($services[WebapiConverter::KEY_SERVICES]); - return array_keys($serviceVersionData); + return array_keys($services[WebapiConverter::KEY_SERVICES][$serviceName]); } /** + * Get a list of all service methods that cannot be executed asynchronously. + * * @param \Magento\Webapi\Model\ServiceMetadata $serviceMetadata * @return array */ @@ -119,14 +131,43 @@ private function getSynchronousOnlyServiceMethods(\Magento\Webapi\Model\ServiceM foreach ($serviceData[Converter::KEY_METHODS] as $method => $methodData) { if ($this->isMethodDataSynchronousOnly($methodData)) { - foreach ($this->getServiceVersions() as $serviceVersion) { - $serviceName = $serviceMetadata->getServiceName($service, $serviceVersion); - if (!array_key_exists($serviceName, $synchronousOnlyServiceMethods)) { - $synchronousOnlyServiceMethods[$serviceName] = []; - } + $this->appendSynchronousOnlyServiceMethodsWithInterface( + $serviceMetadata, + $synchronousOnlyServiceMethods, + $service, + $method + ); + } + } + } - $synchronousOnlyServiceMethods[$serviceName][$method] = true; - } + return array_merge_recursive( + $synchronousOnlyServiceMethods, + $this->getSynchronousOnlyRoutesAsServiceMethods($serviceMetadata) + ); + } + + /** + * Get service methods associated with routes that can't be processed as asynchronous. + * + * @param \Magento\Webapi\Model\ServiceMetadata $serviceMetadata + * @return array + */ + private function getSynchronousOnlyRoutesAsServiceMethods( + \Magento\Webapi\Model\ServiceMetadata $serviceMetadata + ) { + $synchronousOnlyServiceMethods = []; + $serviceRoutes = $this->webapiConfig->getServices()[\Magento\Webapi\Model\Config\Converter::KEY_ROUTES]; + foreach ($serviceRoutes as $serviceRoutePath => $serviceRouteMethods) { + foreach ($serviceRouteMethods as $serviceRouteMethod => $serviceRouteMethodData) { + // Check if the HTTP method associated with the route is not able to be async. + if (in_array(strtoupper($serviceRouteMethod), $this->synchronousOnlyHttpMethods)) { + $this->appendSynchronousOnlyServiceMethodsWithInterface( + $serviceMetadata, + $synchronousOnlyServiceMethods, + $serviceRouteMethodData[WebapiConverter::KEY_SERVICE][WebapiConverter::KEY_SERVICE_CLASS], + $serviceRouteMethodData[WebapiConverter::KEY_SERVICE][WebapiConverter::KEY_SERVICE_METHOD] + ); } } } @@ -134,6 +175,28 @@ private function getSynchronousOnlyServiceMethods(\Magento\Webapi\Model\ServiceM return $synchronousOnlyServiceMethods; } + /** + * @param \Magento\Webapi\Model\ServiceMetadata $serviceMetadata + * @param array $synchronousOnlyServiceMethods + * @param $serviceInterface + * @param $serviceMethod + */ + private function appendSynchronousOnlyServiceMethodsWithInterface( + \Magento\Webapi\Model\ServiceMetadata $serviceMetadata, + array &$synchronousOnlyServiceMethods, + $serviceInterface, + $serviceMethod + ) { + foreach ($this->getServiceVersions($serviceInterface) as $serviceVersion) { + $serviceName = $serviceMetadata->getServiceName($serviceInterface, $serviceVersion); + if (!array_key_exists($serviceName, $synchronousOnlyServiceMethods)) { + $synchronousOnlyServiceMethods[$serviceName] = []; + } + + $synchronousOnlyServiceMethods[$serviceName][$serviceMethod] = true; + } + } + /** * @param array $result * @param $serviceName @@ -153,7 +216,7 @@ private function replaceResponseDefinition(array $result, $serviceName, $methodN } /** - * Check if a method on the given service is defined as synchronous only. + * Check if a method on the given service is defined as synchronous only using XML. * * @param array $methodData * @return bool diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/Rest/Swagger/GeneratorTest.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/Rest/Swagger/GeneratorTest.php index 377c5c2d8b3ab..59ed4cda1678a 100644 --- a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/Rest/Swagger/GeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/Rest/Swagger/GeneratorTest.php @@ -62,6 +62,12 @@ public function testGenerateAsync() $schema['paths']['/V1/customers']['post']['responses'] ); + // 202 Response should not apply to GET requests. + $this->assertArrayNotHasKey( + '202', + $schema['paths']['/V1/customers/me/shippingAddress']['get']['responses'] + ); + // Ensure that the response type has been replaced with the async version. $this->assertEquals( '#/definitions/webapi-async-data-async-response-interface', From 46c1ad96d8f477db92118b00889a16d76623af90 Mon Sep 17 00:00:00 2001 From: Carey Sizer <carey@balanceinternet.com.au> Date: Fri, 23 Mar 2018 17:46:06 +1300 Subject: [PATCH 179/668] Updated Swagger to not show GET requests as part of the async schema These have now been excluded from WebapiAsync module and shouldn't be described in Swagger either --- .../WebapiAsync/Plugin/ServiceMetadata.php | 32 +++++++++++++------ .../Model/Rest/Swagger/GeneratorTest.php | 4 +-- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php b/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php index 11a1d3ab4cf54..c52ac0930177c 100644 --- a/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php +++ b/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php @@ -79,12 +79,14 @@ public function afterGetServicesConfig(\Magento\Webapi\Model\ServiceMetadata $su // Check all of the methods on the service foreach ($serviceData[WebapiConverter::KEY_METHODS] as $methodName => $methodData) { // Exclude service methods that are marked as synchronous only - if (!$this->isServiceMethodSynchronousOnly( + if ($this->isServiceMethodSynchronousOnly( $serviceName, $methodName, $synchronousOnlyServiceMethods )) { - $result = $this->replaceResponseDefinition($result, $serviceName, $methodName); + $this->removeServiceMethodDefinition($result, $serviceName, $methodName); + } else { + $this->replaceResponseDefinition($result, $serviceName, $methodName); } } } @@ -201,18 +203,28 @@ private function appendSynchronousOnlyServiceMethodsWithInterface( * @param array $result * @param $serviceName * @param $methodName - * @return array */ - private function replaceResponseDefinition(array $result, $serviceName, $methodName) + private function removeServiceMethodDefinition(array &$result, $serviceName, $methodName) { - if (!isset($result[$serviceName][WebapiConverter::KEY_METHODS][$methodName]['interface']['out'])) { - return $result; - } + unset($result[$serviceName][WebapiConverter::KEY_METHODS][$methodName]); - $replacement = $this->getResponseDefinitionReplacement(); - $result[$serviceName][WebapiConverter::KEY_METHODS][$methodName]['interface']['out'] = $replacement; + // Remove the service altogether if there is no methods left. + if (count($result[$serviceName][WebapiConverter::KEY_METHODS]) === 0) { + unset($result[$serviceName]); + } + } - return $result; + /** + * @param array $result + * @param $serviceName + * @param $methodName + */ + private function replaceResponseDefinition(array &$result, $serviceName, $methodName) + { + if (isset($result[$serviceName][WebapiConverter::KEY_METHODS][$methodName]['interface']['out'])) { + $replacement = $this->getResponseDefinitionReplacement(); + $result[$serviceName][WebapiConverter::KEY_METHODS][$methodName]['interface']['out'] = $replacement; + } } /** diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/Rest/Swagger/GeneratorTest.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/Rest/Swagger/GeneratorTest.php index 59ed4cda1678a..3e00f900fc302 100644 --- a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/Rest/Swagger/GeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/Rest/Swagger/GeneratorTest.php @@ -64,8 +64,8 @@ public function testGenerateAsync() // 202 Response should not apply to GET requests. $this->assertArrayNotHasKey( - '202', - $schema['paths']['/V1/customers/me/shippingAddress']['get']['responses'] + '/V1/customers/me/shippingAddress', + $schema['paths'] ); // Ensure that the response type has been replaced with the async version. From 57c92a5df4c34298f521df21881be0d83dbedcb4 Mon Sep 17 00:00:00 2001 From: Carey Sizer <carey@balanceinternet.com.au> Date: Fri, 23 Mar 2018 18:22:06 +1300 Subject: [PATCH 180/668] Updated Async Schema URLs so that Swagger UI outputs the correct endpoint following rebase --- app/code/Magento/SwaggerWebapi/etc/frontend/di.xml | 1 - .../Magento/SwaggerWebapiAsync/Model/SchemaType/Async.php | 2 +- .../Test/Unit/Model/SchemaType/AsyncTest.php | 8 +++----- app/code/Magento/SwaggerWebapiAsync/etc/frontend/di.xml | 1 - 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/SwaggerWebapi/etc/frontend/di.xml b/app/code/Magento/SwaggerWebapi/etc/frontend/di.xml index 4e680fe1a27f7..5b54eee0faa79 100644 --- a/app/code/Magento/SwaggerWebapi/etc/frontend/di.xml +++ b/app/code/Magento/SwaggerWebapi/etc/frontend/di.xml @@ -8,7 +8,6 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\SwaggerWebapi\Model\SchemaType\Rest"> <arguments> - <!-- @todo: implement constant once merged with other bulk-api changes --> <argument name="code" xsi:type="string">rest</argument> </arguments> </type> diff --git a/app/code/Magento/SwaggerWebapiAsync/Model/SchemaType/Async.php b/app/code/Magento/SwaggerWebapiAsync/Model/SchemaType/Async.php index 1fa9d623f1cd7..303bc6cd7a561 100644 --- a/app/code/Magento/SwaggerWebapiAsync/Model/SchemaType/Async.php +++ b/app/code/Magento/SwaggerWebapiAsync/Model/SchemaType/Async.php @@ -43,6 +43,6 @@ public function getSchemaUrlPath($store = null) { $store = $store ?? 'all'; - return '/' . $this->code . '/' . $store . '/schema?services=all'; + return '/rest/' . $store . '/' . $this->code . '/schema?services=all'; } } diff --git a/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php b/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php index 4c342896af573..1e1ab3c50fe5e 100644 --- a/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php +++ b/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php @@ -7,7 +7,7 @@ namespace Magento\SwaggerWebapi\Test\Unit\Model\SchemaType; use Magento\Swagger\Api\Data\SchemaTypeInterface; -use Magento\SwaggerWebapi\Model\SchemaType\Async; +use Magento\SwaggerWebapiAsync\Model\SchemaType\Async; class AsyncTest extends \PHPUnit\Framework\TestCase { @@ -21,7 +21,6 @@ class AsyncTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - // @todo: implement constant once merged with other bulk-api changes $this->async = new Async('async'); } @@ -30,7 +29,6 @@ protected function setUp() */ public function testGetCode() { - // @todo: implement constant once merged with other bulk-api changes $this->assertEquals('async', $this->async->getCode()); } @@ -55,11 +53,11 @@ public function getSchemaUrlPathProvider() return [ [ null, - '/async/all/schema?services=all' + '/rest/all/async/schema?services=all' ], [ 'test', - '/async/test/schema?services=all' + '/rest/test/async/schema?services=all' ] ]; } diff --git a/app/code/Magento/SwaggerWebapiAsync/etc/frontend/di.xml b/app/code/Magento/SwaggerWebapiAsync/etc/frontend/di.xml index 6bbcb2d85f564..8d56182324cd4 100644 --- a/app/code/Magento/SwaggerWebapiAsync/etc/frontend/di.xml +++ b/app/code/Magento/SwaggerWebapiAsync/etc/frontend/di.xml @@ -8,7 +8,6 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\SwaggerWebapiAsync\Model\SchemaType\Async"> <arguments> - <!-- @todo: implement constant once merged with other bulk-api changes --> <argument name="code" xsi:type="string">async</argument> </arguments> </type> From 1402f68f701a73f5268acf2a09babff5572bc5dd Mon Sep 17 00:00:00 2001 From: Leonid Poluyanov <lpoluyanov@magento.com> Date: Fri, 23 Mar 2018 09:45:38 +0200 Subject: [PATCH 181/668] MAGETWO-89417: [2.3.x][Functional-Tests] - AdminSwitchWYSIWYGOptionsCest fails on 2.3-develop --- .../Magento/FunctionalTest/Cms/Test/AdminCreateCmsBlockTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsBlockTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsBlockTest.xml index 540f1da21d8a8..77965cfedfd4d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsBlockTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsBlockTest.xml @@ -20,6 +20,7 @@ </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="loginGetFromGeneralFile"/> + <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> </before> <after> <actionGroup ref="logout" stepKey="logout"/> From 32c65b6ba591ef5bcbca61347da7cdaf64fa7938 Mon Sep 17 00:00:00 2001 From: Leonid Poluyanov <lpoluyanov@magento.com> Date: Fri, 23 Mar 2018 10:45:45 +0200 Subject: [PATCH 182/668] MAGETWO-89417: [2.3.x][Functional-Tests] - AdminSwitchWYSIWYGOptionsCest fails on 2.3-develop --- .../Magento/FunctionalTest/Cms/Test/AdminCreateCmsPageTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsPageTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsPageTest.xml index 7e168f9d67cba..3bdd57ef2b9c8 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsPageTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsPageTest.xml @@ -90,6 +90,7 @@ </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="loginGetFromGeneralFile"/> + <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> </before> <after> <actionGroup ref="logout" stepKey="logout"/> From cea006a11d5f6159069369fe51213ff4e0b8eb34 Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Fri, 23 Mar 2018 07:00:05 -0500 Subject: [PATCH 183/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - updated the log path for queue tests --- .../Framework/MessageQueue/UseCase/QueueTestCaseAbstract.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/MessageQueue/UseCase/QueueTestCaseAbstract.php b/dev/tests/integration/testsuite/Magento/Framework/MessageQueue/UseCase/QueueTestCaseAbstract.php index 3a59e79cee45c..4eea5b0b3b71f 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/MessageQueue/UseCase/QueueTestCaseAbstract.php +++ b/dev/tests/integration/testsuite/Magento/Framework/MessageQueue/UseCase/QueueTestCaseAbstract.php @@ -50,9 +50,10 @@ abstract class QueueTestCaseAbstract extends \PHPUnit\Framework\TestCase protected function setUp() { $this->objectManager = Bootstrap::getObjectManager(); + $this->logFilePath = TESTS_TEMP_DIR . "/MessageQueueTestLog.txt"; $this->publisherConsumerController = $this->objectManager->create(PublisherConsumerController::class, [ 'consumers' => $this->consumers, - 'logFilePath' => TESTS_TEMP_DIR . "/MessageQueueTestLog.txt", + 'logFilePath' => $this->logFilePath, 'maxMessages' => $this->maxMessages, 'appInitParams' => \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams() ]); From e7e501d6f5f35f6795a2722901ef5f4cd85b8415 Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Fri, 23 Mar 2018 08:35:47 -0500 Subject: [PATCH 184/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - updated the api functional test - fixed exception thrown in Mass Schedule - fixed REGEXP to match the async request processor --- .../Rest/AsynchronousRequestProcessor.php | 2 +- .../Model/MessageQueue/MassSchedule.php | 7 +- .../api-functional/framework/bootstrap.php | 4 + .../WebapiAsync}/WebapiAsyncBaseTestCase.php | 2 +- .../Model/MessageQueue/BulkScheduleTest.php | 499 +++++++++--------- 5 files changed, 264 insertions(+), 250 deletions(-) rename dev/tests/{integration/testsuite/Magento/WebapiAsync/Model => api-functional/testsuite/Magento/WebapiAsync}/WebapiAsyncBaseTestCase.php (98%) diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php index ccc1303d92955..5b543808f51a0 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php @@ -16,7 +16,7 @@ class AsynchronousRequestProcessor implements RequestProcessorInterface { - const PROCESSOR_PATH = "/async/V\\d+/"; + const PROCESSOR_PATH = "/async\\/V\\d+/"; /** * @var \Magento\Framework\Webapi\Rest\Response diff --git a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php index 2a2f291a7e1c3..a6cec79f58aa3 100644 --- a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php +++ b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php @@ -197,7 +197,12 @@ public function publishMass($topicName, $entitiesArray, $groupId = null) } if (!empty($errors)) { - throw new \Magento\Framework\Webapi\Exception($errors); + throw new \Magento\Framework\Webapi\Exception( + __('Errors while processing entities'), + 0, + \Magento\Framework\Webapi\Exception::HTTP_BAD_REQUEST, + $errors + ); } $result = $this->bulkManagement->scheduleBulk($groupId, $operations, $bulkDescription, $userId); diff --git a/dev/tests/api-functional/framework/bootstrap.php b/dev/tests/api-functional/framework/bootstrap.php index 942582392e89e..fc4ceea393098 100644 --- a/dev/tests/api-functional/framework/bootstrap.php +++ b/dev/tests/api-functional/framework/bootstrap.php @@ -14,6 +14,10 @@ $integrationTestsDir = realpath("{$testsBaseDir}/../integration"); $fixtureBaseDir = $integrationTestsDir . '/testsuite'; +if (!defined('TESTS_TEMP_DIR')) { + define('TESTS_TEMP_DIR', $testsBaseDir . '/tmp'); +} + try { setCustomErrorHandler(); diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/WebapiAsyncBaseTestCase.php b/dev/tests/api-functional/testsuite/Magento/WebapiAsync/WebapiAsyncBaseTestCase.php similarity index 98% rename from dev/tests/integration/testsuite/Magento/WebapiAsync/Model/WebapiAsyncBaseTestCase.php rename to dev/tests/api-functional/testsuite/Magento/WebapiAsync/WebapiAsyncBaseTestCase.php index 089d663e181c1..6b31ca2c0f2e9 100644 --- a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/WebapiAsyncBaseTestCase.php +++ b/dev/tests/api-functional/testsuite/Magento/WebapiAsync/WebapiAsyncBaseTestCase.php @@ -49,7 +49,7 @@ class WebApiAsyncBaseTestCase extends WebapiAbstract protected function setUp() { $this->objectManager = Bootstrap::getObjectManager(); - $this->publisherConsumerController = $this->objectManager->get(PublisherConsumerController::class, [ + $this->publisherConsumerController = $this->objectManager->create(PublisherConsumerController::class, [ 'consumers' => $this->consumers, 'logFilePath' => TESTS_TEMP_DIR . "/MessageQueueTestLog.txt", 'maxMessages' => $this->maxMessages, diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/BulkScheduleTest.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/BulkScheduleTest.php index 277d1f674f42c..840dd7ea006c6 100644 --- a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/BulkScheduleTest.php +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/BulkScheduleTest.php @@ -7,16 +7,16 @@ namespace Magento\WebapiAsync\Model\MessageQueue; use Magento\Catalog\Api\Data\ProductInterface; -use Magento\TestFramework\TestCase\WebapiAbstract; -use Magento\Framework\MessageQueue\Consumer\ConfigInterface as ConsumerConfigInterface; -use Magento\MessageQueue\Model\Cron\ConsumersRunner\PidConsumerManager; -use Magento\Framework\App\DeploymentConfig\FileReader; -use Magento\Framework\App\DeploymentConfig\Writer; -use Magento\Framework\Config\File\ConfigFilePool; -use Magento\Framework\ShellInterface; -use Magento\Framework\Filesystem; -use Magento\Framework\App\Filesystem\DirectoryList; -use Magento\Framework\App\Config\ReinitableConfigInterface; +//use Magento\Framework\MessageQueue\Consumer\ConfigInterface as ConsumerConfigInterface; +//use Magento\MessageQueue\Model\Cron\ConsumersRunner\PidConsumerManager; +//use Magento\Framework\App\DeploymentConfig\FileReader; +//use Magento\Framework\App\DeploymentConfig\Writer; +//use Magento\Framework\Config\File\ConfigFilePool; +//use Magento\Framework\ShellInterface; +//use Magento\Framework\Filesystem; +//use Magento\Framework\App\Filesystem\DirectoryList; +//use Magento\Framework\App\Config\ReinitableConfigInterface; +use Magento\WebapiAsync\WebApiAsyncBaseTestCase; /** * Check async request for product creation service, scheduling bulk to rabbitmq @@ -26,7 +26,7 @@ * @magentoAppIsolation enabled * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class BulkScheduleTest extends WebapiAbstract +class BulkScheduleTest extends WebApiAsyncBaseTestCase { const SERVICE_NAME = 'catalogProductRepositoryV1'; const SERVICE_VERSION = 'V1'; @@ -40,96 +40,100 @@ class BulkScheduleTest extends WebapiAbstract const BULK_UUID_KEY = 'bulk_uuid'; - /** - * @var \Magento\Framework\ObjectManagerInterface - */ - private $objectManager; - - /** - * Consumer config provider - * - * @var ConsumerConfigInterface - */ - private $consumerConfig; - - /** - * @var PidConsumerManager - */ - private $pid; - - /** - * @var FileReader - */ - private $reader; - - /** - * @var \Magento\MessageQueue\Model\Cron\ConsumersRunner - */ - private $consumersRunner; - - /** - * @var Filesystem - */ - private $filesystem; - - /** - * @var ConfigFilePool - */ - private $configFilePool; - - /** - * @var ReinitableConfigInterface - */ - private $appConfig; - - /** - * @var ShellInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $shellMock; - - /** - * @var array - */ - private $config; - - /** - * @inheritdoc - */ - protected function setUp() - { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->shellMock = $this->getMockBuilder(ShellInterface::class) - ->getMockForAbstractClass(); - $this->pid = $this->objectManager->get(PidConsumerManager::class); - $this->consumerConfig = $this->objectManager->get(ConsumerConfigInterface::class); - $this->reader = $this->objectManager->get(FileReader::class); - $this->filesystem = $this->objectManager->get(Filesystem::class); - $this->configFilePool = $this->objectManager->get(ConfigFilePool::class); - $this->appConfig = $this->objectManager->get(ReinitableConfigInterface::class); - - $this->consumersRunner = $this->objectManager->create( - \Magento\MessageQueue\Model\Cron\ConsumersRunner::class, - ['shellBackground' => $this->shellMock] - ); - - $this->config = $this->loadConfig(); - - $this->shellMock->expects($this->any()) - ->method('execute') - ->willReturnCallback(function ($command, $arguments) { - $command = vsprintf($command, $arguments); - $params = - \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams(); - $params['MAGE_DIRS']['base']['path'] = BP; - $params = - 'INTEGRATION_TEST_PARAMS="' . urldecode(http_build_query($params)) . '"'; - $command = - str_replace('bin/magento', 'dev/tests/integration/bin/magento', $command); - $command = $params . ' ' . $command; - - return exec("{$command} > /dev/null &"); - }); - } + protected $consumers = [ + self::ASYNC_CONSUMER_NAME + ]; + +// /** +// * @var \Magento\Framework\ObjectManagerInterface +// */ +// private $objectManager; +// +// /** +// * Consumer config provider +// * +// * @var ConsumerConfigInterface +// */ +// private $consumerConfig; +// +// /** +// * @var PidConsumerManager +// */ +// private $pid; +// +// /** +// * @var FileReader +// */ +// private $reader; +// +// /** +// * @var \Magento\MessageQueue\Model\Cron\ConsumersRunner +// */ +// private $consumersRunner; +// +// /** +// * @var Filesystem +// */ +// private $filesystem; +// +// /** +// * @var ConfigFilePool +// */ +// private $configFilePool; +// +// /** +// * @var ReinitableConfigInterface +// */ +// private $appConfig; +// +// /** +// * @var ShellInterface|\PHPUnit_Framework_MockObject_MockObject +// */ +// private $shellMock; +// +// /** +// * @var array +// */ +// private $config; + +// /** +// * @inheritdoc +// */ +// protected function setUp() +// { +// $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +// $this->shellMock = $this->getMockBuilder(ShellInterface::class) +// ->getMockForAbstractClass(); +// $this->pid = $this->objectManager->get(PidConsumerManager::class); +// $this->consumerConfig = $this->objectManager->get(ConsumerConfigInterface::class); +// $this->reader = $this->objectManager->get(FileReader::class); +// $this->filesystem = $this->objectManager->get(Filesystem::class); +// $this->configFilePool = $this->objectManager->get(ConfigFilePool::class); +// $this->appConfig = $this->objectManager->get(ReinitableConfigInterface::class); +// +// $this->consumersRunner = $this->objectManager->create( +// \Magento\MessageQueue\Model\Cron\ConsumersRunner::class, +// ['shellBackground' => $this->shellMock] +// ); +// +// $this->config = $this->loadConfig(); +// +// $this->shellMock->expects($this->any()) +// ->method('execute') +// ->willReturnCallback(function ($command, $arguments) { +// $command = vsprintf($command, $arguments); +// $params = +// \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams(); +// $params['MAGE_DIRS']['base']['path'] = BP; +// $params = +// 'INTEGRATION_TEST_PARAMS="' . urldecode(http_build_query($params)) . '"'; +// $command = +// str_replace('bin/magento', 'dev/tests/integration/bin/magento', $command); +// $command = $params . ' ' . $command; +// +// return exec("{$command} > /dev/null &"); +// }); +// } /** * @dataProvider productCreationProvider @@ -205,7 +209,7 @@ private function getSimpleProductData($productData = []) } /** - * @param $product + * @param $product * @param string|null $storeCode * @return mixed */ @@ -249,43 +253,6 @@ private function deleteProductRest($sku) return $this->_webApiCall($serviceInfo, ['sku' => $sku]); } - /** - * Checks that pid files are created - * - * @return void - */ - public function testCheckThatAsyncPidFilesWasCreated() - { - $config = $this->config; - $config['cron_consumers_runner'] = ['cron_run' => true]; - $this->writeConfig($config); - - $this->consumersRunner->run(); - - foreach ($this->consumerConfig->getConsumers() as $consumer) { - if ($consumer->getName() == self::ASYNC_CONSUMER_NAME) { - $this->waitConsumerPidFile($consumer->getName()); - } - } - } - - /** - * Tests running of specific consumer and his re-running when it is working - * - * @return void - */ - public function testAsyncConsumerAndRerun() - { - $specificConsumer = self::ASYNC_CONSUMER_NAME; - $config = $this->config; - $config['cron_consumers_runner'] = - ['consumers' => [$specificConsumer], 'max_messages' => null, 'cron_run' => true]; - $this->writeConfig($config); - - $this->reRunConsumersAndCheckPidFiles($specificConsumer); - $this->assertGreaterThan(0, $this->pid->getPid($specificConsumer)); - } - /** * @dataProvider productCreationProvider */ @@ -297,112 +264,150 @@ public function testAsyncProductCreation($product) $this->deleteProductRest($product[ProductInterface::SKU]);//removing product immediately after test passed } - /** - * @param string $specificConsumer - * @return void - */ - private function reRunConsumersAndCheckPidFiles($specificConsumer) - { - $this->consumersRunner->run(); - - sleep(20); - - foreach ($this->consumerConfig->getConsumers() as $consumer) { - $consumerName = $consumer->getName(); - $pidFilePath = $this->pid->getPidFilePath($consumerName); - - if ($consumerName === $specificConsumer) { - $this->assertTrue(file_exists($pidFilePath)); - } else { - $this->assertFalse(file_exists($pidFilePath)); - } - } - } - - /** - * Tests disabling cron job which runs consumers - * - * @return void - */ - public function testCronJobDisabled() - { - $config = $this->config; - $config['cron_consumers_runner'] = ['cron_run' => false]; - - $this->writeConfig($config); - - $this->consumersRunner->run(); - - sleep(20); - - foreach ($this->consumerConfig->getConsumers() as $consumer) { - $pidFilePath = $this->pid->getPidFilePath($consumer->getName()); - $this->assertFalse(file_exists($pidFilePath)); - } - } - - /** - * @param string $consumerName - * @return void - */ - private function waitConsumerPidFile($consumerName) - { - $pidFilePath = $this->pid->getPidFilePath($consumerName); - $i = 0; - do { - sleep(1); - } while (!file_exists($pidFilePath) && ($i++ < 60)); - - sleep(30); - - if (!file_exists($pidFilePath)) { - $this->fail($consumerName . ' pid file does not exist.'); - } - } - - /** - * @return array - */ - private function loadConfig() - { - return $this->reader->load(ConfigFilePool::APP_ENV); - } - - /** - * @param array $config - * @return void - */ - private function writeConfig(array $config) - { - /** @var Writer $writer */ - $writer = $this->objectManager->get(Writer::class); - $writer->saveConfig([ConfigFilePool::APP_ENV => $config]); - } - - /** - * @inheritdoc - */ - protected function tearDown() - { - foreach ($this->consumerConfig->getConsumers() as $consumer) { - $consumerName = $consumer->getName(); - $pid = $this->pid->getPid($consumerName); - - if ($pid && $this->pid->isRun($consumerName)) { - posix_kill($pid, SIGKILL); - } - - $path = $this->pid->getPidFilePath($consumerName); - if (file_exists($path)) { - unlink($path); - } - } - - $this->filesystem->getDirectoryWrite(DirectoryList::CONFIG)->writeFile( - $this->configFilePool->getPath(ConfigFilePool::APP_ENV), - "<?php\n return array();\n" - ); - $this->writeConfig($this->config); - $this->appConfig->reinit(); - } +// /** +// * Checks that pid files are created +// * +// * @return void +// */ +// public function testCheckThatAsyncPidFilesWasCreated() +// { +// $config = $this->config; +// $config['cron_consumers_runner'] = ['cron_run' => true]; +// $this->writeConfig($config); +// +// $this->consumersRunner->run(); +// +// foreach ($this->consumerConfig->getConsumers() as $consumer) { +// if ($consumer->getName() == self::ASYNC_CONSUMER_NAME) { +// $this->waitConsumerPidFile($consumer->getName()); +// } +// } +// } +// +// /** +// * Tests running of specific consumer and his re-running when it is working +// * +// * @return void +// */ +// public function testAsyncConsumerAndRerun() +// { +// $specificConsumer = self::ASYNC_CONSUMER_NAME; +// $config = $this->config; +// $config['cron_consumers_runner'] = +// ['consumers' => [$specificConsumer], 'max_messages' => null, 'cron_run' => true]; +// $this->writeConfig($config); +// +// $this->reRunConsumersAndCheckPidFiles($specificConsumer); +// $this->assertGreaterThan(0, $this->pid->getPid($specificConsumer)); +// } + + +// /** +// * @param string $specificConsumer +// * @return void +// */ +// private function reRunConsumersAndCheckPidFiles($specificConsumer) +// { +// $this->consumersRunner->run(); +// +// sleep(20); +// +// foreach ($this->consumerConfig->getConsumers() as $consumer) { +// $consumerName = $consumer->getName(); +// $pidFilePath = $this->pid->getPidFilePath($consumerName); +// +// if ($consumerName === $specificConsumer) { +// $this->assertTrue(file_exists($pidFilePath)); +// } else { +// $this->assertFalse(file_exists($pidFilePath)); +// } +// } +// } +// +// /** +// * Tests disabling cron job which runs consumers +// * +// * @return void +// */ +// public function testCronJobDisabled() +// { +// $config = $this->config; +// $config['cron_consumers_runner'] = ['cron_run' => false]; +// +// $this->writeConfig($config); +// +// $this->consumersRunner->run(); +// +// sleep(20); +// +// foreach ($this->consumerConfig->getConsumers() as $consumer) { +// $pidFilePath = $this->pid->getPidFilePath($consumer->getName()); +// $this->assertFalse(file_exists($pidFilePath)); +// } +// } +// +// /** +// * @param string $consumerName +// * @return void +// */ +// private function waitConsumerPidFile($consumerName) +// { +// $pidFilePath = $this->pid->getPidFilePath($consumerName); +// $i = 0; +// do { +// sleep(1); +// } while (!file_exists($pidFilePath) && ($i++ < 60)); +// +// sleep(30); +// +// if (!file_exists($pidFilePath)) { +// $this->fail($consumerName . ' pid file does not exist.'); +// } +// } +// +// /** +// * @return array +// */ +// private function loadConfig() +// { +// return $this->reader->load(ConfigFilePool::APP_ENV); +// } +// +// /** +// * @param array $config +// * @return void +// */ +// private function writeConfig(array $config) +// { +// /** @var Writer $writer */ +// $writer = $this->objectManager->get(Writer::class); +// $writer->saveConfig([ConfigFilePool::APP_ENV => $config]); +// } +// +// /** +// * @inheritdoc +// */ +// protected function tearDown() +// { +// foreach ($this->consumerConfig->getConsumers() as $consumer) { +// $consumerName = $consumer->getName(); +// $pid = $this->pid->getPid($consumerName); +// +// if ($pid && $this->pid->isRun($consumerName)) { +// posix_kill($pid, SIGKILL); +// } +// +// $path = $this->pid->getPidFilePath($consumerName); +// if (file_exists($path)) { +// unlink($path); +// } +// } +// +// $this->filesystem->getDirectoryWrite(DirectoryList::CONFIG)->writeFile( +// $this->configFilePool->getPath(ConfigFilePool::APP_ENV), +// "<?php\n return array();\n" +// ); +// $this->writeConfig($this->config); +// $this->appConfig->reinit(); +// } } From 47c2238dcdf2dee6717b4e3229b96975a45cf5a6 Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Fri, 23 Mar 2018 08:36:51 -0500 Subject: [PATCH 185/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - moved test to a proper directory --- .../testsuite/Magento/WebapiAsync/Model}/BulkScheduleTest.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dev/tests/{integration/testsuite/Magento/WebapiAsync/Model/MessageQueue => api-functional/testsuite/Magento/WebapiAsync/Model}/BulkScheduleTest.php (100%) diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/BulkScheduleTest.php b/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php similarity index 100% rename from dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/BulkScheduleTest.php rename to dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php From 2248d290c341e395d4e884bf4ae742f48f4fed5a Mon Sep 17 00:00:00 2001 From: olysenko <olysenko@magento.com> Date: Fri, 23 Mar 2018 15:58:53 +0200 Subject: [PATCH 186/668] MAGETWO-89382: Automate MAGETWO-46344 MFTF --- .../ActionGroup/MoveCategoryActionGroup.xml | 23 +++ .../StorefrontProductActionGroup.xml | 13 ++ .../Catalog/Data/CategoryData.xml | 8 + .../Catalog/Page/AdminCategoryPage.xml | 1 + .../AdminCategorySidebarTreeSection.xml | 1 + ...minCategoryWarningMessagesPopupSection.xml | 16 ++ .../Catalog/Test/DeleteCategoriesTest.xml | 161 ++++++++++++++++++ 7 files changed, 223 insertions(+) create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/MoveCategoryActionGroup.xml create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryWarningMessagesPopupSection.xml create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/MoveCategoryActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/MoveCategoryActionGroup.xml new file mode 100644 index 0000000000000..d08dc9ad7f893 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/MoveCategoryActionGroup.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="MoveCategoryActionGroup"> + <arguments> + <argument name="childCategory"/> + <argument name="parentCategory"/> + </arguments> + <click stepKey="expandAllCategoriesTree" selector="{{AdminCategorySidebarTreeSection.expandAll}}"/> + <waitForAjaxLoad stepKey="waitForCategoriesExpand"/> + <dragAndDrop selector1="{{AdminCategorySidebarTreeSection.category('childCategory')}}" selector2="{{AdminCategorySidebarTreeSection.category('parentCategory')}}" stepKey="moveCategory"/> + <waitForElementVisible selector="{{AdminCategoryWarningMessagesPopupSection.warningMessage}}" stepKey="waitForWarningMessageVisible"/> + <see selector="{{AdminCategoryWarningMessagesPopupSection.warningMessage}}" userInput="This operation can take a long time" stepKey="seeWarningMessage"/> + <click selector="{{AdminCategoryWarningMessagesPopupSection.okButton}}" stepKey="clickOkButtonOnWarningPopup"/> + </actionGroup> + </actionGroups> \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontProductActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontProductActionGroup.xml index ffc1687bc9f58..ddefa1a839804 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontProductActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontProductActionGroup.xml @@ -23,4 +23,17 @@ <see userInput="{{product.custom_attributes[description]}}" selector="{{StorefrontProductInfoMainSection.productDescription}}" stepKey="assertProductDescription"/> <see userInput="{{product.custom_attributes[short_description]}}" selector="{{StorefrontProductInfoMainSection.productShortDescription}}" stepKey="assertProductShortDescription"/> </actionGroup> + <!-- Check the simple product on the product page without description --> + <actionGroup name="StorefrontCheckSimpleProductNoDescription"> + <arguments> + <argument name="product"/> + </arguments> + <seeInCurrentUrl url="/{{product.custom_attributes[url_key]}}.html" stepKey="checkUrl"/> + <seeInTitle userInput="{{product.name}}" stepKey="AssertProductNameInTitle"/> + <see userInput="{{product.name}}" selector="{{StorefrontProductInfoMainSection.productName}}" stepKey="assertProductName"/> + <see userInput="{{product.sku}}" selector="{{StorefrontProductInfoMainSection.productSku}}" stepKey="assertProductSku"/> + <see userInput="${{product.price}}.00" selector="{{StorefrontProductInfoMainSection.productPrice}}" stepKey="assertProductPrice"/> + <see userInput="IN STOCK" selector="{{StorefrontProductInfoMainSection.productStockStatus}}" stepKey="assertInStock"/> + <seeElement selector="{{StorefrontProductInfoMainSection.AddToCart}}" stepKey="assertAddToCart" /> + </actionGroup> </actionGroups> \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/CategoryData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/CategoryData.xml index 5de996809b704..d76c1286f2636 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/CategoryData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/CategoryData.xml @@ -22,5 +22,13 @@ <data key="name_lwr" unique="suffix">simplesubcategory</data> <data key="is_active">true</data> <data key="include_in_menu">true</data> + <var key="parent_id" entityType="category" entityKey="id"/> + </entity> + <entity name="NewRootCategory" type="category"> + <data key="name" unique="suffix">NewRootCategory</data> + <data key="name_lwr" unique="suffix">newrootcategory</data> + <data key="is_active">true</data> + <data key="include_in_menu">true</data> + <data key="parent_id">1</data> </entity> </entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/AdminCategoryPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/AdminCategoryPage.xml index f51d2e8a28939..7cb4ca0e7987d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/AdminCategoryPage.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/AdminCategoryPage.xml @@ -18,5 +18,6 @@ <section name="AdminCategoryProductsGridSection"/> <section name="AdminCategoryModalSection"/> <section name="AdminCategoryMessagesSection"/> + <section name="AdminCategoryWarningMessagesPopupSection"/> </page> </pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySidebarTreeSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySidebarTreeSection.xml index e914c80c3e6ac..9c8ee70874372 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySidebarTreeSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySidebarTreeSection.xml @@ -14,5 +14,6 @@ <element name="categoryTreeRoot" type="text" selector="div.x-tree-root-node>li.x-tree-node:first-of-type>div.x-tree-node-el:first-of-type" timeout="30"/> <element name="categoryInTree" type="text" selector="//a/span[contains(text(), '{{name}}')]" parameterized="true" timeout="30"/> <element name="categoryInTreeUnderRoot" type="text" selector="//div[@class='x-tree-root-node']/li/ul/li[@class='x-tree-node']/div/a/span[contains(text(), '{{name}}')]" parameterized="true"/> + <element name="category" type="button" selector="//span[contains(text(),'{{var1}}')]" parameterized="true"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryWarningMessagesPopupSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryWarningMessagesPopupSection.xml new file mode 100644 index 0000000000000..6f9b0738a451e --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryWarningMessagesPopupSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminCategoryWarningMessagesPopupSection"> + <element name="warningMessage" type="text" selector=".modal-inner-wrap .modal-content .message.message-notice"/> + <element name="cancelButton" type="button" selector=".modal-inner-wrap .action-secondary"/> + <element name="okButton" type="button" selector=".modal-inner-wrap .action-primary" timeout="30"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml new file mode 100644 index 0000000000000..c4de4866519e0 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="DeleteCategoriesTest"> + <annotations> + <features value="Delete categories"/> + <stories value="Delete categories"/> + <title value="Delete categories."/> + <description value="Delete categories."/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-46344"/> + <group value="category"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategoryC"/> + <createData entity="_defaultProduct" stepKey="createProduct1"> + <requiredEntity createDataKey="createCategoryC"/> + </createData> + <createData entity="SimpleSubCategory" stepKey="createSubCategory"> + <requiredEntity createDataKey="createCategoryC"/> + </createData> + <createData entity="_defaultProduct" stepKey="createProduct2"> + <requiredEntity createDataKey="createSubCategory"/> + </createData> + <createData entity="_defaultCategory" stepKey="createCategoryB"/> + <createData entity="_defaultProduct" stepKey="createProduct3"> + <requiredEntity createDataKey="createCategoryB"/> + </createData> + <createData entity="NewRootCategory" stepKey="createNewRootCategoryA"/> + </before> + <after> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin1"/> + <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage1"/> + <waitForPageLoad time="30" stepKey="waitForPageLoad1"/> + <click selector="{{AdminCategorySidebarTreeSection.category($$createNewRootCategoryA.name$$)}}" stepKey="openNewRootCategory"/> + <waitForPageLoad stepKey="waitForPageLoad1a"/> + <seeElement selector="{{AdminCategoryMainActionsSection.DeleteButton}}" stepKey="assertDeleteButtonIsPresent"/> + <!--Move categories from Default Category to NewRootCategory. --> + <actionGroup ref="MoveCategoryActionGroup" stepKey="MoveCategoryBToNewRootCategory"> + <argument name="childCategory" value="$$createCategoryC.name$$"/> + <argument name="parentCategory" value="$$createNewRootCategoryA.name$$"/> + </actionGroup> + <actionGroup ref="MoveCategoryActionGroup" stepKey="MoveCategoryCToNewRootCategory"> + <argument name="childCategory" value="$$createCategoryB.name$$"/> + <argument name="parentCategory" value="$$createNewRootCategoryA.name$$"/> + </actionGroup> + <!-- Change root category for Main Website Store. --> + <amOnPage stepKey="s1" url="{{AdminSystemStorePage.url}}"/> + <waitForPageLoad stepKey="waitForPageLoad2" /> + <click stepKey="s2" selector="{{AdminStoresGridSection.resetButton}}"/> + <waitForPageLoad stepKey="waitForPageLoad3" time="10"/> + <fillField stepKey="s4" selector="{{AdminStoresGridSection.storeGrpFilterTextField}}" userInput="Main Website Store"/> + <click stepKey="s5" selector="{{AdminStoresGridSection.searchButton}}"/> + <waitForPageLoad stepKey="waitForPageLoad4"/> + <click stepKey="s7" selector="{{AdminStoresGridSection.storeGrpNameInFirstRow}}" /> + <waitForPageLoad stepKey="waitForPageLoad5" /> + <selectOption selector="{{AdminNewStoreGroupSection.storeRootCategoryDropdown}}" userInput="{{NewRootCategory.name}}" stepKey="setNewCategoryForStoreGroup"/> + <click selector="{{AdminNewStoreViewActionsSection.saveButton}}" stepKey="clickSaveStoreGroup"/> + <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForModal"/> + <see selector="{{AdminConfirmationModalSection.title}}" userInput="Warning message" stepKey="seeWarning"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="acceptModal" /> + <waitForElementVisible selector="{{AdminStoresGridSection.storeFilterTextField}}" stepKey="waitForPageReload"/> + <see userInput="You saved the store." stepKey="seeSavedMessage"/> + + <!-- Perform cli reindex. --> + <!--<magentoCLI command="indexer:reindex" stepKey="magentoCli"/>--> + + <!-- Delete Default Root Category. --> + <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage2"/> + <waitForPageLoad time="30" stepKey="waitForPageLoad6"/> + <click selector="{{AdminCategorySidebarTreeSection.category('Default Category')}}" stepKey="clickOnDefaultRootCategory"/> + <waitForPageLoad stepKey="waitForPageLoad7" /> + <seeElement selector="{{AdminCategoryMainActionsSection.DeleteButton}}" stepKey="assertDeleteButtonIsPresent1"/> + <click selector="{{AdminCategoryMainActionsSection.DeleteButton}}" stepKey="DeleteDefaultRootCategory"/> + <waitForElementVisible selector="{{AdminCategoryModalSection.ok}}" stepKey="waitForModal1" /> + <click selector="{{AdminCategoryModalSection.ok}}" stepKey="acceptModal1"/> + <waitForElementVisible selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="waitForPageReload1"/> + <!-- Verify categories 1 and 3 their products. --> + <amOnPage url="{{StorefrontHomePage.url}}" stepKey="amOnHomePage"/> + <waitForPageLoad stepKey="homeWaitForPageLoad"/> + + <!--<click selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategoryC.name$$)}}" stepKey="browseClickCategoryC"/>--> + <!--<actionGroup ref="StorefrontCheckCategoryActionGroup" stepKey="browseAssertCategoryC">--> + <!--<argument name="category" value="$$createCategoryC$$"/>--> + <!--<!– @TODO: Change to scalar value after MQE-498 is implemented –>--> + <!--<argument name="productCount" value="CONST.two"/>--> + <!--</actionGroup>--> + <!--<actionGroup ref="StorefrontCheckCategorySimpleProduct" stepKey="browseAssertCategoryProduct1">--> + <!--<argument name="product" value="$$createProduct1$$"/>--> + <!--</actionGroup>--> + + <moveMouseOver selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategoryC.name$$)}}" stepKey="hoverCategory"/> + <waitForElementVisible selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createSubCategory.name$$)}}" stepKey="waitForSubcategory"/> + <click selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createSubCategory.name$$)}}" stepKey="browseClickSubCategory"/> + <actionGroup ref="StorefrontCheckCategoryActionGroup" stepKey="browseAssertSubcategory"> + <argument name="category" value="$$createSubCategory$$"/> + <!-- @TODO: Change to scalar value after MQE-498 is implemented --> + <argument name="productCount" value="CONST.one"/> + </actionGroup> + <actionGroup ref="StorefrontCheckCategorySimpleProduct" stepKey="browseAssertCategoryProduct2"> + <argument name="product" value="$$createProduct2$$"/> + </actionGroup> + + <!--<actionGroup ref="StorefrontCheckCategoryActionGroup" stepKey="browseAssertCategoryB">--> + <!--<argument name="category" value="$$createCategoryB$$"/>--> + <!--<!– @TODO: Change to scalar value after MQE-498 is implemented –>--> + <!--<argument name="productCount" value="CONST.one"/>--> + <!--</actionGroup>--> + <!--<actionGroup ref="StorefrontCheckCategorySimpleProduct" stepKey="browseAssertCategoryProduct3">--> + <!--<argument name="product" value="$$createProduct3$$"/>--> + <!--</actionGroup>--> + + <!-- Delete Categories 1(with subcategory) and 3. --> + <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage3"/> + <waitForPageLoad time="30" stepKey="waitForPageLoad8"/> + <actionGroup ref="DeleteCategory" stepKey="deleteCategoryC"> + <argument name="categoryEntity" value="$$createCategoryC$$"/> + </actionGroup> + <actionGroup ref="DeleteCategory" stepKey="deleteCategoryB"> + <argument name="categoryEntity" value="$$createCategoryB$$"/> + </actionGroup> + <!-- Verify categories 1 and 3 are absent --> + <amOnPage url="{{StorefrontHomePage.url}}" stepKey="amOnHomePage1"/> + <waitForPageLoad stepKey="homeWaitForPageLoad1"/> + <dontSee selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategoryB.name$$)}}" stepKey="browseClickCategoryB"/> + <dontSee selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategoryC.name$$)}}" stepKey="browseClickCategoryC"/> + <!-- Verify products 1-3 are available on storefront --> + <amOnPage url="{{StorefrontHomePage.url}}$$createProduct1.custom_attributes[url_key]$$.html" stepKey="amOnProduct1Page"/> + <waitForPageLoad stepKey="product1WaitForPageLoad"/> + <actionGroup ref="StorefrontCheckSimpleProductNoDescription" stepKey="browseAssertProduct1Page"> + <argument name="product" value="$$createProduct1$$"/> + </actionGroup> + <amOnPage url="{{StorefrontHomePage.url}}$$createProduct2.custom_attributes[url_key]$$.html" stepKey="amOnProduct2Page"/> + <waitForPageLoad stepKey="product2WaitForPageLoad"/> + <actionGroup ref="StorefrontCheckSimpleProductNoDescription" stepKey="browseAssertProduct2Page"> + <argument name="product" value="$$createProduct2$$"/> + </actionGroup> + <amOnPage url="{{StorefrontHomePage.url}}$$createProduct3.custom_attributes[url_key]$$.html" stepKey="amOnProduct3Page"/> + <waitForPageLoad stepKey="product3WaitForPageLoad"/> + <actionGroup ref="StorefrontCheckSimpleProductNoDescription" stepKey="browseAssertProduct3Page"> + <argument name="product" value="$$createProduct3$$"/> + </actionGroup> + <!-- Rename New Root Category to Default category --> + <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage4"/> + <waitForPageLoad time="30" stepKey="waitForPageLoad9"/> + <click selector="{{AdminCategorySidebarTreeSection.category('$$createNewRootCategoryA.name$$')}}" stepKey="clickOnDefaultRootCategory2"/> + <waitForPageLoad stepKey="waitForPageLoad10" /> + <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="Default Category" stepKey="enterCategoryName"/> + <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategory"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="assertSuccess"/> + </test> +</tests> \ No newline at end of file From 3007b002799c801cab68350d4c8e392cd0506109 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Fri, 23 Mar 2018 17:18:41 +0200 Subject: [PATCH 187/668] MAGETWO-72861: Visual Merchandiser category edit performance issue --- app/code/Magento/CatalogRule/Plugin/Indexer/Category.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogRule/Plugin/Indexer/Category.php b/app/code/Magento/CatalogRule/Plugin/Indexer/Category.php index 29fc7c72bfb15..50e3703087680 100644 --- a/app/code/Magento/CatalogRule/Plugin/Indexer/Category.php +++ b/app/code/Magento/CatalogRule/Plugin/Indexer/Category.php @@ -35,7 +35,7 @@ public function afterSave( \Magento\Catalog\Model\Category $result ) { /** @var \Magento\Catalog\Model\Category $result */ - $productIds = $result->getAffectedProductIds(); + $productIds = $result->getChangedProductIds(); if (!empty($productIds) && !$this->productRuleProcessor->isIndexerScheduled()) { $this->productRuleProcessor->reindexList($productIds); } From a97a662766b92cfcfb59bffbc1d6345415f2fb67 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Fri, 23 Mar 2018 10:30:30 -0500 Subject: [PATCH 188/668] MAGETWO-89082: Update composer dependencies - update amqp dependency --- .../Magento/Framework/Amqp/composer.json | 26 ------------------- lib/internal/Magento/Framework/composer.json | 1 + 2 files changed, 1 insertion(+), 26 deletions(-) delete mode 100644 lib/internal/Magento/Framework/Amqp/composer.json diff --git a/lib/internal/Magento/Framework/Amqp/composer.json b/lib/internal/Magento/Framework/Amqp/composer.json deleted file mode 100644 index f92b3ec22cb5b..0000000000000 --- a/lib/internal/Magento/Framework/Amqp/composer.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "magento/framework-amqp", - "description": "N/A", - "config": { - "sort-packages": true - }, - "type": "magento2-library", - "version": "100.1.0-dev", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], - "require": { - "magento/framework": "100.3.*", - "php": "~7.1.3||~7.2.0", - "php-amqplib/php-amqplib": "~2.7.0" - }, - "autoload": { - "psr-4": { - "Magento\\Framework\\Amqp\\": "" - }, - "files": [ - "registration.php" - ] - } -} diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json index 4dd2d8a0402df..b446bf384075f 100644 --- a/lib/internal/Magento/Framework/composer.json +++ b/lib/internal/Magento/Framework/composer.json @@ -27,6 +27,7 @@ "magento/zendframework1": "~1.13.0", "monolog/monolog": "^1.17", "oyejorge/less.php": "~1.7.0", + "php-amqplib/php-amqplib": "~2.7.0", "symfony/console": "~4.0.0", "symfony/process": "~4.0.0", "tedivm/jshrink": "~1.1.0", From e7d48302a4c87a7e71ce1b4eb58de25d524ce320 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 23 Mar 2018 11:13:02 -0500 Subject: [PATCH 189/668] MAGETWO-89292: Implement SDL from prototype - implement empty field --- app/code/Magento/GraphQl/etc/di.xml | 2 - app/code/Magento/GraphQl/etc/schema.graphql | 1 - .../Config/Converter/Normalizer/Output.php | 84 +++---------------- .../GraphQl/Config/GraphQlReader.php | 80 +++++++++++++++++- .../GraphQlReader/Reader/ObjectType.php | 53 +++++++++++- 5 files changed, 138 insertions(+), 82 deletions(-) diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 49b1393141df0..c34efb900bbf9 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -106,8 +106,6 @@ <arguments> <argument name="normalizers" xsi:type="array"> <item name="output" xsi:type="object">Magento\Framework\GraphQl\Config\Converter\Normalizer\Output</item> - <item name="input" xsi:type="object">Magento\Framework\GraphQl\Config\Converter\Normalizer\Input</item> - <item name="enum" xsi:type="object">Magento\Framework\GraphQl\Config\Converter\Normalizer\Enum</item> </argument> </arguments> </type> diff --git a/app/code/Magento/GraphQl/etc/schema.graphql b/app/code/Magento/GraphQl/etc/schema.graphql index 498da368074fb..03c264d5cfb65 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphql +++ b/app/code/Magento/GraphQl/etc/schema.graphql @@ -1,5 +1,4 @@ type Query { - placeholder: String } input FilterTypeInput { diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Output.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Output.php index 01551b81bc0e6..417758cf2bdc6 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Output.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Output.php @@ -33,81 +33,21 @@ public function __construct(FormatterInterface $formatter) */ public function normalize(array $source): array { - - $types = $this->normalizeTypes($source); - $interfaces = $this->normalizeInterfaces($source); - foreach ($interfaces as $interface) { - foreach ($types as $name => $type) { - if (isset($type['implements']) - && isset($type['implements'][$interface['name']]) - && isset($type['implements'][$interface['name']]['copyFields']) - && $type['implements'][$interface['name']]['copyFields'] === "true" - ) { - $types[$name]['fields'] = isset($type['fields']) - ? array_merge($type['fields'], $interface['fields']) : $interface['fields']; + foreach ($source as $interface) { + if ($interface['type'] == 'graphql_interface') { + foreach ($source as $typeName => $type) { + if (isset($type['implements']) + && isset($type['implements'][$interface['name']]) + && isset($type['implements'][$interface['name']]['copyFields']) + && $type['implements'][$interface['name']]['copyFields'] === true + ) { + $source[$typeName]['fields'] = isset($type['fields']) + ? array_replace($interface['fields'], $type['fields']) : $interface['fields']; + } } } } - return array_merge($types, $interfaces); - } - - /** - * Normalize all output types inside of GraphQL configuration array. - * - * @param array $source - * @return array - */ - private function normalizeTypes(array $source): array - { - return $this->normalizeStructure( - $source, - 'graphql_type', - 'OutputType', - ['name'] - ); - } - - /** - * Normalize all output interfaces inside of GraphQL configuration array. - * - * @param array $source - * @return array - */ - private function normalizeInterfaces(array $source): array - { - return $this->normalizeStructure( - $source, - 'graphql_interface', - 'OutputInterface', - ['name', 'typeResolver'] - ); - } - - /** - * Output normalized array read from GraphQL configuration. - * - * @param array $source - * @param string $configKey - * @param string $configType - * @param array $requiredAttributes - * @return array - */ - private function normalizeStructure( - array $source, - string $configKey, - string $configType, - array $requiredAttributes - ) : array { - $entries = []; - foreach ($source['config'][0]['type'] as $entry) { - if ($entry['type'] !== $configType) { - continue; - } - $entries[$entry['name']] = array_intersect_key($entry, array_flip($requiredAttributes)); - $entries[$entry['name']]['type'] = $configKey; - $entries[$entry['name']] = array_merge($entries[$entry['name']], $this->formatter->format($entry)); - } - return $entries; + return $source; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php index 09a2054c2976e..7e78ab482a321 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php @@ -10,9 +10,13 @@ use Magento\Framework\Config\FileResolverInterface; use Magento\Framework\GraphQl\Config\GraphQlReader\TypeReader; use Magento\Framework\Config\ReaderInterface; +use Magento\Framework\GraphQl\Config\Converter\NormalizerComposite; class GraphQlReader implements ReaderInterface { + + const GRAPHQL_PLACEHOLDER_FIELD_NAME = 'placeholder_graphql_field'; + /** * File locator * @@ -36,20 +40,28 @@ class GraphQlReader implements ReaderInterface */ private $defaultScope; + /** + * @var NormalizerComposite + */ + private $normalizer; + /** * @param FileResolverInterface $fileResolver * @param TypeReader $typeReader + * @param NormalizerComposite $normalizer * @param string $fileName * @param string $defaultScope */ public function __construct( FileResolverInterface $fileResolver, TypeReader $typeReader, + NormalizerComposite $normalizer, $fileName = 'schema.graphql', $defaultScope = 'global' ) { $this->fileResolver = $fileResolver; $this->typeReader = $typeReader; + $this->normalizer = $normalizer; $this->defaultScope = $defaultScope; $this->fileName = $fileName; } @@ -75,11 +87,13 @@ public function read($scope = null) : array // Keep declarations from current partial schema, add missing declarations from all previously read schemas $knownTypes = $partialSchemaTypes + $knownTypes; $schemaContent = implode("\n", $knownTypes); + $partialResult = $this->readPartialTypes($schemaContent); $result = array_replace_recursive($result, $partialResult); } + $result = $this->copyInterfaceFieldsToConcreteTypes($result); return $result; } @@ -93,7 +107,29 @@ public function read($scope = null) : array private function readPartialTypes(string $graphQlSchemaContent) : array { $partialResult = []; + $placeholderField = self::GRAPHQL_PLACEHOLDER_FIELD_NAME; + $typesKindsPattern = '(type|interface|input)'; + $enumKindsPattern = '(enum)'; + $typeNamePattern = '([_A-Za-z][_0-9A-Za-z]+)'; + $typeDefinitionPattern = '([^\{]*)(\{[\s\t\n\r^\}]*\})'; + $spacePattern = '([\s\t\n\r]+)'; + + //add placeholder in empty types + $graphQlSchemaContent = preg_replace( + "/{$typesKindsPattern}{$spacePattern}{$typeNamePattern}{$spacePattern}{$typeDefinitionPattern}/im", + "\$1\$2\$3\$4\$5{\n{$placeholderField}: String\n}", + $graphQlSchemaContent + ); + + //add placeholder in empty enums + $graphQlSchemaContent = preg_replace( + "/{$enumKindsPattern}{$spacePattern}{$typeNamePattern}{$spacePattern}{$typeDefinitionPattern}/im", + "\$1\$2\$3\$4\$5{\n{$placeholderField}\n}", + $graphQlSchemaContent + ); + $schema = \GraphQL\Utils\BuildSchema::build($graphQlSchemaContent); + foreach ($schema->getTypeMap() as $typeName => $typeMeta) { // Only process custom types and skip built-in object types if ((strpos($typeName, '__') !== 0 && (!$typeMeta instanceof \GraphQL\Type\Definition\ScalarType))) { @@ -103,6 +139,18 @@ private function readPartialTypes(string $graphQlSchemaContent) : array } } } + + //remove parsed placeholders + foreach ($partialResult as $typeName => $partialResultType) { + if (isset($partialResultType['fields'][$placeholderField])) { + //unset placeholder for fields + unset($partialResult[$typeName]['fields'][$placeholderField]); + } elseif (isset($partialResultType['items'][$placeholderField])) { + //unset placeholder for enums + unset($partialResult[$typeName]['items'][$placeholderField]); + } + } + return $partialResult; } @@ -115,12 +163,12 @@ private function readPartialTypes(string $graphQlSchemaContent) : array private function parseTypes($graphQlSchemaContent) : array { $typeKindsPattern = '(type|interface|union|enum|input)'; - $typeNamePattern = '[_A-Za-z][_0-9A-Za-z]+'; - $typeDefinitionPattern = '[^\{]*(\{[^\}]*\})'; + $typeNamePattern = '([_A-Za-z][_0-9A-Za-z]+)'; + $typeDefinitionPattern = '([^\{]*)(\{[^\}]*\})'; $spacePattern = '[\s\t\n\r]+'; preg_match_all( - "/{$typeKindsPattern}{$spacePattern}({$typeNamePattern}){$spacePattern}{$typeDefinitionPattern}/i", + "/{$typeKindsPattern}{$spacePattern}{$typeNamePattern}{$spacePattern}{$typeDefinitionPattern}/i", $graphQlSchemaContent, $matches ); @@ -131,4 +179,30 @@ private function parseTypes($graphQlSchemaContent) : array $parsedTypes = array_combine($matches[2], $matches[0]); return $parsedTypes; } + + /** + * Copy interface fields to concrete types + * + * @param array $source + * @return array + */ + public function copyInterfaceFieldsToConcreteTypes(array $source): array + { + foreach ($source as $interface) { + if ($interface['type'] == 'graphql_interface') { + foreach ($source as $typeName => $type) { + if (isset($type['implements']) + && isset($type['implements'][$interface['name']]) + && isset($type['implements'][$interface['name']]['copyFields']) + && $type['implements'][$interface['name']]['copyFields'] === true + ) { + $source[$typeName]['fields'] = isset($type['fields']) + ? array_replace($interface['fields'], $type['fields']) : $interface['fields']; + } + } + } + } + + return $source; + } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php index fa7b364f4b5fe..cf96f52b91a7e 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php @@ -46,12 +46,11 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array 'fields' => [], // Populated later ]; - $interfaces = $typeMeta->getInterfaces(); - foreach ($interfaces as $interfaceMeta) { - $interfaceName = $interfaceMeta->name; + $interfacesNames = $this->readCopyFieldsAnnotation($typeMeta->astNode->directives); + foreach ($interfacesNames as $interfaceName) { $result['implements'][$interfaceName] = [ 'interface' => $interfaceName, - 'copyFields' => true // TODO: Configure in separate config + 'copyFields' => true ]; } @@ -69,4 +68,50 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array return null; } } + + /** + * Read copyFields annotation for a specific node if exists + * + * @param \GraphQL\Language\AST\NodeList $directives + * @return string[]|null + */ + public function readCopyFieldsAnnotation(\GraphQL\Language\AST\NodeList $directives) : array + { + foreach ($directives as $directive) { + if ($directive->name->value == 'implements') { + foreach ($directive->arguments as $directiveArgument) { + if ($directiveArgument->name->value == 'interfaces') { + if ($directiveArgument->value->kind == 'ListValue') { + $interfacesNames = []; + foreach ($directiveArgument->value->values as $stringValue) { + $interfacesNames[] = $stringValue->value; + } + return $interfacesNames; + } else { + return [$directiveArgument->value->value]; + } + } + } + } + } + return []; + } + + /** + * Find interface graphql type in array list of strings + * + * @param \GraphQL\Type\Definition\InterfaceType $interfacesType + * @param string[] $interfacesNames + * @return bool + */ + public function isInInterfaceTypeInList( + \GraphQL\Type\Definition\InterfaceType $interfacesType, + array $interfacesNames + ) : bool { + if (in_array($interfacesType->name, $interfacesNames)) { + return true; + } else { + return false; + } + } } From ed6dbf548ea7ef5eb5af5e01402c8587b4d78bd7 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Fri, 23 Mar 2018 18:15:18 +0200 Subject: [PATCH 190/668] MAGETWO-72861: Visual Merchandiser category edit performance issue --- .../CatalogRule/Test/Unit/Plugin/Indexer/CategoryTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Unit/Plugin/Indexer/CategoryTest.php b/app/code/Magento/CatalogRule/Test/Unit/Plugin/Indexer/CategoryTest.php index 5822e01853deb..71e2093b0e325 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Plugin/Indexer/CategoryTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Plugin/Indexer/CategoryTest.php @@ -32,7 +32,7 @@ protected function setUp() ); $this->subject = $this->createPartialMock( \Magento\Catalog\Model\Category::class, - ['getAffectedProductIds', '__wakeUp'] + ['getChangedProductIds', '__wakeUp'] ); $this->plugin = (new ObjectManager($this))->getObject( @@ -46,7 +46,7 @@ protected function setUp() public function testAfterSaveWithoutAffectedProductIds() { $this->subject->expects($this->any()) - ->method('getAffectedProductIds') + ->method('getChangedProductIds') ->will($this->returnValue([])); $this->productRuleProcessor->expects($this->never()) @@ -60,7 +60,7 @@ public function testAfterSave() $productIds = [1, 2, 3]; $this->subject->expects($this->any()) - ->method('getAffectedProductIds') + ->method('getChangedProductIds') ->will($this->returnValue($productIds)); $this->productRuleProcessor->expects($this->once()) From 3769ea476dbd7378ae4f2c138217c6f50bb86b0d Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 23 Mar 2018 12:56:28 -0500 Subject: [PATCH 191/668] MAGETWO-89292: Implement SDL from prototype - implement copy interface --- .../GraphQl/Config/GraphQlReader.php | 178 +++++++++++++----- 1 file changed, 132 insertions(+), 46 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php index 7e78ab482a321..7cde4306304f5 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php @@ -14,7 +14,6 @@ class GraphQlReader implements ReaderInterface { - const GRAPHQL_PLACEHOLDER_FIELD_NAME = 'placeholder_graphql_field'; /** @@ -71,11 +70,11 @@ public function __construct( */ public function read($scope = null) : array { - $result = []; + $results = []; $scope = $scope ?: $this->defaultScope; $schemaFiles = $this->fileResolver->get($this->fileName, $scope); if (!count($schemaFiles)) { - return $result; + return $results; } /** @@ -84,17 +83,18 @@ public function read($scope = null) : array $knownTypes = []; foreach ($schemaFiles as $partialSchemaContent) { $partialSchemaTypes = $this->parseTypes($partialSchemaContent); + // Keep declarations from current partial schema, add missing declarations from all previously read schemas $knownTypes = $partialSchemaTypes + $knownTypes; $schemaContent = implode("\n", $knownTypes); - $partialResult = $this->readPartialTypes($schemaContent); + $partialResults = $this->readPartialTypes($schemaContent); - $result = array_replace_recursive($result, $partialResult); + $results = array_replace_recursive($results, $partialResults); } - $result = $this->copyInterfaceFieldsToConcreteTypes($result); - return $result; + $results = $this->copyInterfaceFieldsToConcreteTypes($results); + return $results; } @@ -106,52 +106,25 @@ public function read($scope = null) : array */ private function readPartialTypes(string $graphQlSchemaContent) : array { - $partialResult = []; - $placeholderField = self::GRAPHQL_PLACEHOLDER_FIELD_NAME; - $typesKindsPattern = '(type|interface|input)'; - $enumKindsPattern = '(enum)'; - $typeNamePattern = '([_A-Za-z][_0-9A-Za-z]+)'; - $typeDefinitionPattern = '([^\{]*)(\{[\s\t\n\r^\}]*\})'; - $spacePattern = '([\s\t\n\r]+)'; - - //add placeholder in empty types - $graphQlSchemaContent = preg_replace( - "/{$typesKindsPattern}{$spacePattern}{$typeNamePattern}{$spacePattern}{$typeDefinitionPattern}/im", - "\$1\$2\$3\$4\$5{\n{$placeholderField}: String\n}", - $graphQlSchemaContent - ); + $partialResults = []; - //add placeholder in empty enums - $graphQlSchemaContent = preg_replace( - "/{$enumKindsPattern}{$spacePattern}{$typeNamePattern}{$spacePattern}{$typeDefinitionPattern}/im", - "\$1\$2\$3\$4\$5{\n{$placeholderField}\n}", - $graphQlSchemaContent - ); + $graphQlSchemaContent = $this->addPlaceHolderInSchema($graphQlSchemaContent); $schema = \GraphQL\Utils\BuildSchema::build($graphQlSchemaContent); foreach ($schema->getTypeMap() as $typeName => $typeMeta) { // Only process custom types and skip built-in object types if ((strpos($typeName, '__') !== 0 && (!$typeMeta instanceof \GraphQL\Type\Definition\ScalarType))) { - $partialResult[$typeName] = $this->typeReader->read($typeMeta); - if (!$partialResult[$typeName]) { + $partialResults[$typeName] = $this->typeReader->read($typeMeta); + if (!$partialResults[$typeName]) { throw new \LogicException("'{$typeName}' cannot be processed."); } } } - //remove parsed placeholders - foreach ($partialResult as $typeName => $partialResultType) { - if (isset($partialResultType['fields'][$placeholderField])) { - //unset placeholder for fields - unset($partialResult[$typeName]['fields'][$placeholderField]); - } elseif (isset($partialResultType['items'][$placeholderField])) { - //unset placeholder for enums - unset($partialResult[$typeName]['items'][$placeholderField]); - } - } + $partialResults = $this->removePlaceholderFromResults($partialResults); - return $partialResult; + return $partialResults; } /** @@ -172,11 +145,20 @@ private function parseTypes($graphQlSchemaContent) : array $graphQlSchemaContent, $matches ); - /** - * $matches[0] is an indexed array with the whole type definitions - * $matches[2] is an indexed array with type names - */ - $parsedTypes = array_combine($matches[2], $matches[0]); + + $parsedTypes = []; + + if (!empty($matches)) { + foreach ($matches[0] as $matchKey => $matchValue) { + $matches[0][$matchKey] = $this->convertInterfacesToAnnotations($matchValue); + } + + /** + * $matches[0] is an indexed array with the whole type definitions + * $matches[2] is an indexed array with type names + */ + $parsedTypes = array_combine($matches[2], $matches[0]); + } return $parsedTypes; } @@ -186,7 +168,7 @@ private function parseTypes($graphQlSchemaContent) : array * @param array $source * @return array */ - public function copyInterfaceFieldsToConcreteTypes(array $source): array + private function copyInterfaceFieldsToConcreteTypes(array $source): array { foreach ($source as $interface) { if ($interface['type'] == 'graphql_interface') { @@ -205,4 +187,108 @@ public function copyInterfaceFieldsToConcreteTypes(array $source): array return $source; } + + /** + * Find the implements statement and convert them to annotation to enable copy fields feature + * + * @param string $graphQlSchemaContent + * @return string + */ + private function convertInterfacesToAnnotations(string $graphQlSchemaContent): string + { + $implementsKindsPattern = 'implements'; + $typeNamePattern = '([_A-Za-z][_0-9A-Za-z]+)'; + $spacePattern = '([\s\t\n\r]+)'; + $spacePatternNotMandatory = '[\s\t\n\r]*'; + preg_match_all( + "/{$spacePattern}{$implementsKindsPattern}{$spacePattern}{$typeNamePattern}" + . "(,{$spacePatternNotMandatory}$typeNamePattern)*/im", + $graphQlSchemaContent, + $allMatchesForImplements + ); + + + if (!empty($allMatchesForImplements)) { + foreach (array_unique($allMatchesForImplements[0]) as $implementsString) { + $implementsStatementString = preg_replace( + "/{$spacePattern}{$implementsKindsPattern}{$spacePattern}/m", + '', + $implementsString + ); + preg_match_all( + "/{$typeNamePattern}+/im", + $implementsStatementString, + $implementationsMatches + ); + + if (!empty($implementationsMatches)) { + $annotationString = ' @implements(interfaces: ['; + foreach ($implementationsMatches[0] as $interfaceName) { + $annotationString.= "\"{$interfaceName}\", "; + } + $annotationString = rtrim($annotationString, ', '); + $annotationString .= '])'; + $graphQlSchemaContent = str_replace($implementsString, $annotationString, $graphQlSchemaContent); + } + + } + } + + return $graphQlSchemaContent; + } + + /** + * Add a placeholder field into the schema to allow parser to not throw error on empty types + * This method is paired with @see self::removePlaceholderFromResults() + * This is needed so that the placeholder doens't end up in the actual schema + * + * @param string $graphQlSchemaContent + * @return string + */ + private function addPlaceHolderInSchema(string $graphQlSchemaContent) :string + { + $placeholderField = self::GRAPHQL_PLACEHOLDER_FIELD_NAME; + $typesKindsPattern = '(type|interface|input)'; + $enumKindsPattern = '(enum)'; + $typeNamePattern = '([_A-Za-z][_0-9A-Za-z]+)'; + $typeDefinitionPattern = '([^\{]*)(\{[\s\t\n\r^\}]*\})'; + $spacePattern = '([\s\t\n\r]+)'; + + //add placeholder in empty types + $graphQlSchemaContent = preg_replace( + "/{$typesKindsPattern}{$spacePattern}{$typeNamePattern}{$spacePattern}{$typeDefinitionPattern}/im", + "\$1\$2\$3\$4\$5{\n{$placeholderField}: String\n}", + $graphQlSchemaContent + ); + + //add placeholder in empty enums + $graphQlSchemaContent = preg_replace( + "/{$enumKindsPattern}{$spacePattern}{$typeNamePattern}{$spacePattern}{$typeDefinitionPattern}/im", + "\$1\$2\$3\$4\$5{\n{$placeholderField}\n}", + $graphQlSchemaContent + ); + return $graphQlSchemaContent; + } + + /** + * Remove parsed placeholders as these should not be present in final result + * + * @param array $partialResults + * @return array + */ + private function removePlaceholderFromResults(array $partialResults) : array + { + $placeholderField = self::GRAPHQL_PLACEHOLDER_FIELD_NAME; + //remove parsed placeholders + foreach ($partialResults as $typeKeyName => $partialResultTypeArray) { + if (isset($partialResultTypeArray['fields'][$placeholderField])) { + //unset placeholder for fields + unset($partialResults[$typeKeyName]['fields'][$placeholderField]); + } elseif (isset($partialResultTypeArray['items'][$placeholderField])) { + //unset placeholder for enums + unset($partialResults[$typeKeyName]['items'][$placeholderField]); + } + } + return $partialResults; + } } From c6fa26a9b77ec5700bdcf8754429fabb739bf6eb Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 23 Mar 2018 13:45:10 -0500 Subject: [PATCH 192/668] MAGETWO-89292: Implement SDL from prototype - only add fields that are not from the interface --- .../Magento/BundleGraphQl/etc/schema.graphql | 44 ------- .../Magento/CatalogGraphQl/etc/schema.graphql | 108 ------------------ .../etc/schema.graphql | 43 ------- .../DownloadableGraphQl/etc/schema.graphql | 42 ------- .../GroupedProductGraphQl/etc/schema.graphql | 42 ------- 5 files changed, 279 deletions(-) diff --git a/app/code/Magento/BundleGraphQl/etc/schema.graphql b/app/code/Magento/BundleGraphQl/etc/schema.graphql index 29a0851ab8a75..27ff71628955f 100644 --- a/app/code/Magento/BundleGraphQl/etc/schema.graphql +++ b/app/code/Magento/BundleGraphQl/etc/schema.graphql @@ -1,4 +1,3 @@ - type BundleItem { option_id: Int title: String @@ -28,49 +27,6 @@ type BundleProduct implements ProductInterface, PhysicalProductInterface, Custom ship_bundle_items: ShipBundleItemsEnum dynamic_weight: Boolean items: [BundleItem] - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - weight: Float - options: [CustomizableOptionInterface] - manufacturer: Int } enum PriceViewEnum { diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphql b/app/code/Magento/CatalogGraphQl/etc/schema.graphql index c897a8559c69f..1ec984faf2bc4 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphql +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphql @@ -226,11 +226,6 @@ type ProductCategoryLinks { type ProductLinks implements ProductLinksInterface { - sku: String - link_type: String - linked_product_sku: String - linked_product_type: String - position: Int } interface ProductLinksInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductLinkTypeResolverComposite") { @@ -301,9 +296,6 @@ interface PhysicalProductInterface @typeResolver(class: "Magento\\CatalogGraphQl type CustomizableAreaOption implements CustomizableOptionInterface { value: CustomizableAreaValue product_sku: String - title: String - required: Boolean - sort_order: Int } type CustomizableAreaValue { @@ -316,9 +308,6 @@ type CustomizableAreaValue { type CustomizableDateOption implements CustomizableOptionInterface { value: CustomizableDateValue product_sku: String - title: String - required: Boolean - sort_order: Int } type CustomizableDateValue { @@ -329,9 +318,6 @@ type CustomizableDateValue { type CustomizableDropDownOption implements CustomizableOptionInterface { value: [CustomizableDropDownValue] - title: String - required: Boolean - sort_order: Int } type CustomizableDropDownValue { @@ -346,9 +332,6 @@ type CustomizableDropDownValue { type CustomizableFieldOption implements CustomizableOptionInterface { value: CustomizableFieldValue product_sku: String - title: String - required: Boolean - sort_order: Int } type CustomizableFieldValue { @@ -361,9 +344,6 @@ type CustomizableFieldValue { type CustomizableFileOption implements CustomizableOptionInterface { value: CustomizableFileValue product_sku: String - title: String - required: Boolean - sort_order: Int } type CustomizableFileValue { @@ -387,9 +367,6 @@ interface CustomizableProductInterface @typeResolver(class: "Magento\\CatalogGra type CustomizableRadioOption implements CustomizableOptionInterface { value: [CustomizableRadioValue] - title: String - required: Boolean - sort_order: Int } type CustomizableRadioValue { @@ -402,95 +379,10 @@ type CustomizableRadioValue { } type VirtualProduct implements ProductInterface, CustomizableProductInterface { - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - options: [CustomizableOptionInterface] - manufacturer: Int } type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface { - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - weight: Float - options: [CustomizableOptionInterface] - manufacturer: Int } type Products { diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql b/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql index 3724ea4876a02..66cc43a1b538e 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql +++ b/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql @@ -1,49 +1,6 @@ type ConfigurableProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface { configurable_product_links: [SimpleProduct] configurable_product_options: [ConfigurableProductOptions] - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - weight: Float - options: [CustomizableOptionInterface] - manufacturer: Int } type ConfigurableProductOptions { diff --git a/app/code/Magento/DownloadableGraphQl/etc/schema.graphql b/app/code/Magento/DownloadableGraphQl/etc/schema.graphql index a01bc0bb9eb2e..321b56289b15c 100644 --- a/app/code/Magento/DownloadableGraphQl/etc/schema.graphql +++ b/app/code/Magento/DownloadableGraphQl/etc/schema.graphql @@ -3,48 +3,6 @@ type DownloadableProduct implements ProductInterface, CustomizableProductInterfa downloadable_product_links: [DownloadableProductLinks] links_purchased_separately: Int links_title: String - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - options: [CustomizableOptionInterface] - manufacturer: Int } enum DownloadableFileTypeEnum { diff --git a/app/code/Magento/GroupedProductGraphQl/etc/schema.graphql b/app/code/Magento/GroupedProductGraphQl/etc/schema.graphql index 9674d526fc616..fd680e3a95e82 100644 --- a/app/code/Magento/GroupedProductGraphQl/etc/schema.graphql +++ b/app/code/Magento/GroupedProductGraphQl/etc/schema.graphql @@ -1,47 +1,5 @@ type GroupedProduct implements ProductInterface, PhysicalProductInterface { items: [GroupedProductItem] - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - weight: Float - manufacturer: Int } type GroupedProductItem { From f08e103c7ba45a8604e701a82a71b21f0346bf61 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Fri, 23 Mar 2018 15:30:08 -0500 Subject: [PATCH 193/668] MAGETWO-89569: Update composer/composer dependency --- composer.json | 8 ++++---- composer.lock | 2 +- lib/internal/Magento/Framework/composer.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 089756a750bda..b14bb531c849c 100644 --- a/composer.json +++ b/composer.json @@ -40,15 +40,16 @@ "colinmollenhour/cache-backend-redis": "1.10.4", "colinmollenhour/credis": "1.8.2", "colinmollenhour/php-redis-session-abstract": "~1.3.8", - "composer/composer": "~1.6.0", - "magento/composer": "1.3.0.x-dev", + "composer/composer": "^1.6", "elasticsearch/elasticsearch": "~2.0|~5.1", + "magento/composer": "1.3.0.x-dev", "magento/magento-composer-installer": ">=0.1.11", "magento/zendframework1": "dev-master", "monolog/monolog": "^1.17", "oyejorge/less.php": "~1.7.0", "pelago/emogrifier": "^2.0.0", "php-amqplib/php-amqplib": "2.5.*", + "phpseclib/mcrypt_compat": "1.0.4", "phpseclib/phpseclib": "2.0.*", "ramsey/uuid": "~3.7.3", "symfony/console": "~4.0.0", @@ -83,8 +84,7 @@ "zendframework/zend-text": "^2.6.0", "zendframework/zend-uri": "^2.5.1", "zendframework/zend-validator": "^2.6.0", - "zendframework/zend-view": "^2.8.1", - "phpseclib/mcrypt_compat": "1.0.4" + "zendframework/zend-view": "^2.8.1" }, "require-dev": { "friendsofphp/php-cs-fixer": "~2.10.0", diff --git a/composer.lock b/composer.lock index 563ed47dd80ed..7e350983dee1f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "03cd971b78790a885bd0a45354a34d90", + "content-hash": "c2f827106b25e61999eec2b51090b369", "packages": [ { "name": "braintree/braintree_php", diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json index 23032f7e6d2f0..c725413bf0533 100644 --- a/lib/internal/Magento/Framework/composer.json +++ b/lib/internal/Magento/Framework/composer.json @@ -23,7 +23,7 @@ "ext-xsl": "*", "lib-libxml": "*", "colinmollenhour/php-redis-session-abstract": "~1.3.8", - "composer/composer": "~1.6.0", + "composer/composer": "^1.6", "magento/zendframework1": "~1.13.0", "monolog/monolog": "^1.17", "oyejorge/less.php": "~1.7.0", From d76b7882d4908afb53ddac5683fe116a19169d45 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Fri, 23 Mar 2018 15:45:50 -0500 Subject: [PATCH 194/668] MAGETWO-88936: Address performance for products - Generalize resolvers - Implement Grouped - Implement only asking for EAV attributes present in request --- .../Magento/BundleGraphQl/etc/graphql.xml | 2 +- .../Model/Config/AttributeReader.php | 19 +-- .../Model/Resolver/ChildProduct.php} | 21 ++- .../CatalogGraphQl/Model/Resolver/Product.php | 59 +++++++ .../Model/Resolver/Product/CategoryLinks.php | 77 +++++++++ .../Model/Resolver/Product/EntityIdToId.php | 73 +++++++++ .../Resolver/Product/MediaGalleryEntries.php | 71 +++++++++ .../Model/Resolver/Product/NewFromTo.php | 67 ++++++++ .../Model/Resolver/Product/Options.php | 86 ++++++++++ .../Product/Formatter => Product}/Price.php | 52 ++++-- .../Model/Resolver/Product/ProductLinks.php | 79 ++++++++++ .../Model/Resolver/Product/TierPrices.php | 72 +++++++++ .../Model/Resolver/Products.php | 4 +- .../Products/Attributes/Collection.php | 97 ++++++++++++ .../DataProvider/Deferred/Product.php | 45 ++++-- .../Products/DataProvider/Product.php | 23 +-- .../Product/Formatter/BaseModelData.php | 27 ---- .../Product/Formatter/CustomAttributes.php | 32 ---- .../Product/Formatter/EntityIdToId.php | 46 ------ .../Product/Formatter/MediaGalleryEntries.php | 37 ----- .../Product/Formatter/NewFromTo.php | 35 ---- .../Product/Formatter/Options.php | 52 ------ .../Product/Formatter/ProductLinks.php | 45 ------ .../Product/Formatter/TierPrices.php | 38 ----- .../Product/FormatterComposite.php | 44 ------ .../Product/FormatterInterface.php | 25 --- .../Model/Resolver/Products/Query/Filter.php | 76 ++++----- .../Model/Resolver/Products/Query/Search.php | 30 +++- app/code/Magento/CatalogGraphQl/etc/di.xml | 1 - .../Magento/CatalogGraphQl/etc/graphql.xml | 18 +-- .../Magento/CatalogGraphQl/etc/graphql/di.xml | 15 -- .../Products/DataProvider/ProductPlugin.php | 149 ------------------ .../Product/Formatter/ConfigurableOptions.php | 52 ------ .../ConfigurableProductPostProcessor.php | 116 -------------- .../Model/Variant/Collection.php | 55 +++---- .../DownloadableOptions.php | 70 +++++--- .../DownloadableGraphQl/etc/graphql.xml | 4 +- .../DownloadableGraphQl/etc/graphql/di.xml | 7 - .../Model/Resolver/GroupedItems.php | 32 ++++ .../Product/Formatter/ProductLinks.php | 46 ------ .../Resolver/Products/Links/Collection.php | 102 ++++++++++++ .../Query/GroupedItemsPostProcessor.php | 4 +- .../GroupedProductGraphQl/etc/graphql.xml | 4 +- .../GroupedProductGraphQl/etc/graphql/di.xml | 7 - 44 files changed, 1077 insertions(+), 939 deletions(-) rename app/code/Magento/{BundleGraphQl/Model/Resolver/Links/Product.php => CatalogGraphQl/Model/Resolver/ChildProduct.php} (74%) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CategoryLinks.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php rename app/code/Magento/CatalogGraphQl/Model/Resolver/{Products/DataProvider/Product/Formatter => Product}/Price.php (74%) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Attributes/Collection.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BaseModelData.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/CustomAttributes.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/EntityIdToId.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/MediaGalleryEntries.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/NewFromTo.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Options.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/TierPrices.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterComposite.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterInterface.php delete mode 100644 app/code/Magento/ConfigurableProductGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php delete mode 100644 app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ConfigurableOptions.php delete mode 100644 app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/Query/ConfigurableProductPostProcessor.php rename app/code/Magento/DownloadableGraphQl/Model/Resolver/{Products/DataProvider/Product/Formatter => Product}/DownloadableOptions.php (68%) create mode 100644 app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php delete mode 100644 app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php create mode 100644 app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Links/Collection.php diff --git a/app/code/Magento/BundleGraphQl/etc/graphql.xml b/app/code/Magento/BundleGraphQl/etc/graphql.xml index e464c338ae3eb..1d90da0c35730 100644 --- a/app/code/Magento/BundleGraphQl/etc/graphql.xml +++ b/app/code/Magento/BundleGraphQl/etc/graphql.xml @@ -36,7 +36,7 @@ <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price of the selected option"/> <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="One of FIXED, PERCENT, or DYNAMIC"/> <field xsi:type="ScalarOutputField" name="can_change_quantity" type="Boolean" description="Indicates whether the customer can change the number of items for this option"/> - <field xsi:type="ObjectOutputField" name="product" type="ProductInterface" resolver="Magento\BundleGraphQl\Model\Resolver\Links\Product" description="The ProductInterface object, which contains details about this product option"/> + <field xsi:type="ObjectOutputField" name="product" type="ProductInterface" resolver="Magento\CatalogGraphQl\Model\Resolver\ChildProduct" description="The ProductInterface object, which contains details about this product option"/> </type> <type xsi:type="Enum" name="ShipBundleItemsEnum"> <item name="together">TOGETHER</item> diff --git a/app/code/Magento/CatalogGraphQl/Model/Config/AttributeReader.php b/app/code/Magento/CatalogGraphQl/Model/Config/AttributeReader.php index df820e38615e7..435842ca273b1 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Config/AttributeReader.php +++ b/app/code/Magento/CatalogGraphQl/Model/Config/AttributeReader.php @@ -11,8 +11,7 @@ use Magento\Framework\GraphQl\Type\Entity\MapperInterface; use Magento\Framework\Reflection\TypeProcessor; use Magento\EavGraphQl\Model\Resolver\Query\Type; -use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory; -use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection; +use Magento\CatalogGraphQl\Model\Resolver\Products\Attributes\Collection; /** * Adds custom/eav attribute to Catalog product types in the GraphQL config. @@ -30,23 +29,23 @@ class AttributeReader implements ReaderInterface private $typeLocator; /** - * @var CollectionFactory + * @var Collection */ - private $collectionFactory; + private $collection; /** * @param MapperInterface $mapper * @param Type $typeLocator - * @param CollectionFactory $collectionFactory + * @param Collection $collection */ public function __construct( MapperInterface $mapper, Type $typeLocator, - CollectionFactory $collectionFactory + Collection $collection ) { $this->mapper = $mapper; $this->typeLocator = $typeLocator; - $this->collectionFactory = $collectionFactory; + $this->collection = $collection; } /** @@ -61,12 +60,8 @@ public function read($scope = null) : array { $targetStructures = $this->mapper->getMappedTypes(\Magento\Catalog\Model\Product::ENTITY); $config =[]; - /** @var Collection $collection */ - $collection = $this->collectionFactory->create(); - $collection->addFieldToFilter('is_user_defined', '1'); - $collection->addFieldToFilter('attribute_code', ['neq' => 'cost']); /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */ - foreach ($collection as $attribute) { + foreach ($this->collection->getAttributes() as $attribute) { $attributeCode = $attribute->getAttributeCode(); $locatedType = $this->typeLocator->getType( $attributeCode, diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/ChildProduct.php similarity index 74% rename from app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/ChildProduct.php index 94a9825062b70..402e86c8bed75 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/ChildProduct.php @@ -5,7 +5,7 @@ */ declare(strict_types = 1); -namespace Magento\BundleGraphQl\Model\Resolver\Links; +namespace Magento\CatalogGraphQl\Model\Resolver; use GraphQL\Type\Definition\ResolveInfo; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred\Product as ProductDataProvider; @@ -18,7 +18,7 @@ /** * {@inheritdoc} */ -class Product implements ResolverInterface +class ChildProduct implements ResolverInterface { /** * @var ProductDataProvider @@ -51,6 +51,7 @@ public function resolve(Field $field, array $value = null, array $args = null, $ throw new GraphQlInputException(__('No child sku found for product link.')); } $this->productDataProvider->addProductSku($value['sku']); + $this->productDataProvider->addEavAttributes($this->getProductFields($info)); $result = function () use ($value) { return $this->productDataProvider->getProductBySku($value['sku']); @@ -58,4 +59,20 @@ public function resolve(Field $field, array $value = null, array $args = null, $ return $this->valueFactory->create($result); } + + /** + * Return field names for all requested product fields. + * + * @param ResolveInfo $info + * @return string[] + */ + private function getProductFields(ResolveInfo $info) + { + $fieldNames = []; + foreach ($info->fieldNodes as $node) { + $fieldNames[] = $node->name->value; + } + + return $fieldNames; + } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php new file mode 100644 index 0000000000000..9308fe3b4866c --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; + +/** + * Class Product + */ +class Product implements ResolverInterface +{ + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * {@inheritDoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + if (!isset($value['model'])) { + return null; + } + + $result = function () use ($value) { + /** @var \Magento\Catalog\Model\Product $productModel */ + $productModel = $value['model']; + $productData = $productModel->getData(); + + if (!empty($productModel->getCustomAttributes())) { + foreach ($productModel->getCustomAttributes() as $customAttribute) { + if (!isset($productData[$customAttribute->getAttributeCode()])) { + $productData[$customAttribute->getAttributeCode()] = $customAttribute->getValue(); + } + } + } + + $data = array_replace($value, $productData); + return $data; + }; + + return $this->valueFactory->create($result); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CategoryLinks.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CategoryLinks.php new file mode 100644 index 0000000000000..88d8f422eb9ce --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CategoryLinks.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Model\Product; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; + +/** + * Fixed the id related data in the product data + * + * {@inheritdoc} + */ +class CategoryLinks implements ResolverInterface +{ + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @var \Magento\Catalog\Model\ResourceModel\Product + */ + private $productResource; + + /** + * @param ValueFactory $valueFactory + * @param \Magento\Catalog\Model\ResourceModel\Product $productResource + */ + public function __construct( + ValueFactory $valueFactory, + \Magento\Catalog\Model\ResourceModel\Product $productResource + ) { + $this->valueFactory = $valueFactory; + $this->productResource = $productResource; + } + + /** + * {@inheritDoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + if (!isset($value['model'])) { + return null; + } + + /** @var Product $product */ + $product = $value['model']; + + $categories = []; + $categoryLinks = $this->productResource->getCategoryIds($product); + foreach ($categoryLinks as $position => $catLink) { + $categories[] = + ['position' => $position, 'category_id' => $catLink]; + } + + $result = function () use ($categories) { + return $categories; + }; + + return $this->valueFactory->create($result); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php new file mode 100644 index 0000000000000..e0f5cbe27b658 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php @@ -0,0 +1,73 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Model\Product; +use Magento\Framework\EntityManager\MetadataPool; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; + +/** + * Fixed the id related data in the product data + * + * {@inheritdoc} + */ +class EntityIdToId implements ResolverInterface +{ + /** + * @var MetadataPool + */ + private $metadataPool; + + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param MetadataPool $metadataPool + * @param ValueFactory $valueFactory + */ + public function __construct(MetadataPool $metadataPool, ValueFactory $valueFactory) + { + $this->metadataPool = $metadataPool; + $this->valueFactory = $valueFactory; + } + + /** + * {@inheritDoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + if (!isset($value['model'])) { + return null; + } + + /** @var Product $product */ + $product = $value['model']; + + $id = $product->getData( + $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField() + ); + + $result = function () use ($id) { + return $id; + }; + + return $this->valueFactory->create($result); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php new file mode 100644 index 0000000000000..7df31bf7fb60e --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php @@ -0,0 +1,71 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Catalog\Model\Product; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; + +/** + * Format a product's media gallery information to conform to GraphQL schema representation + */ +class MediaGalleryEntries implements ResolverInterface +{ + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param ValueFactory $valueFactory + */ + public function __construct(ValueFactory $valueFactory) + { + $this->valueFactory = $valueFactory; + } + + /** + * Format product's media gallery entry data to conform to GraphQL schema + * + * {@inheritdoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + if (!isset($value['model'])) { + return null; + } + + /** @var Product $product */ + $product = $value['model']; + + $mediaGalleryEntries = []; + if (!empty($product->getMediaGalleryEntries())) { + foreach ($product->getMediaGalleryEntries() as $key => $entry) { + $mediaGalleryEntries[$key] = $entry->getData(); + if ($entry->getExtensionAttributes() && $entry->getExtensionAttributes()->getVideoContent()) { + $mediaGalleryEntries[$key]['video_content'] + = $entry->getExtensionAttributes()->getVideoContent()->getData(); + } + } + } + + $result = function () use ($mediaGalleryEntries) { + return $mediaGalleryEntries; + }; + + return $this->valueFactory->create($result); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php new file mode 100644 index 0000000000000..9fb09070c375e --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php @@ -0,0 +1,67 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Catalog\Model\Product; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; + +/** + * Format the new from and to typo of legacy fields news_from_date and news_to_date + */ +class NewFromTo implements ResolverInterface +{ + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param ValueFactory $valueFactory + */ + public function __construct(ValueFactory $valueFactory) + { + $this->valueFactory = $valueFactory; + } + + /** + * Transfer data from legacy news_from_date and news_to_date to new names corespondent fields + * + * {@inheritdoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + + if (!isset($value['model'])) { + return null; + } + + /** @var Product $product */ + $product = $value['model']; + $attributeName = substr_replace($field->getName(), 's', 3, 0); + + $data = null; + if ($product->getData($attributeName)) { + $data = $product->getData($attributeName); + } + + $result = function () use ($data) { + return $data; + }; + + return $this->valueFactory->create($result); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php new file mode 100644 index 0000000000000..8485f54dfa6c9 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Option; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; + +/** + * Format a product's option information to conform to GraphQL schema representation + */ +class Options implements ResolverInterface +{ + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param ValueFactory $valueFactory + */ + public function __construct(ValueFactory $valueFactory) + { + $this->valueFactory = $valueFactory; + } + + /** + * Format product's option data to conform to GraphQL schema + * + * {@inheritdoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + if (!isset($value['model'])) { + return null; + } + + /** @var Product $product */ + $product = $value['model']; + + $options = null; + if (!empty($product->getOptions())) { + $options = []; + /** @var Option $option */ + foreach ($product->getOptions() as $key => $option) { + $options[$key] = $option->getData(); + $options[$key]['required'] = $option->getIsRequire(); + $options[$key]['product_sku'] = $option->getProductSku(); + + $values = $option->getValues() ?: []; + /** @var Option\Value $value */ + foreach ($values as $valueKey => $value) { + $options[$key]['value'][$valueKey] = $value->getData(); + $options[$key]['value'][$valueKey]['price_type'] + = $value->getPriceType() !== null ? strtoupper($value->getPriceType()) : 'DYNAMIC'; + } + + if (empty($values)) { + $options[$key]['value'] = $option->getData(); + $options[$key]['value']['price_type'] + = $option->getPriceType() !== null ? strtoupper($option->getPriceType()) : 'DYNAMIC'; + } + } + } + + $result = function () use ($options) { + return $options; + }; + + return $this->valueFactory->create($result); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Price.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php similarity index 74% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Price.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php index f1a0b11caae84..dc412b8da9336 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Price.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php @@ -5,38 +5,54 @@ */ declare(strict_types = 1); -namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; +namespace Magento\CatalogGraphQl\Model\Resolver\Product; +use GraphQL\Type\Definition\ResolveInfo; use Magento\Catalog\Model\Product; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; use Magento\Framework\Pricing\PriceInfo\Factory as PriceInfoFactory; use Magento\Framework\Pricing\Amount\AmountInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\Pricing\Adjustment\AdjustmentInterface; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; use Magento\Catalog\Pricing\Price\RegularPrice; use Magento\Catalog\Pricing\Price\FinalPrice; /** * Format a product's price information to conform to GraphQL schema representation */ -class Price implements FormatterInterface +class Price implements ResolverInterface { - /** @var StoreManagerInterface */ + /** + * @var StoreManagerInterface + */ private $storeManager; - /** @var PriceInfoFactory */ + /** + * @var PriceInfoFactory + */ private $priceInfoFactory; + /** + * @var ValueFactory + */ + private $valueFactory; + /** * @param StoreManagerInterface $storeManager * @param PriceInfoFactory $priceInfoFactory + * @param ValueFactory $valueFactory */ public function __construct( StoreManagerInterface $storeManager, - PriceInfoFactory $priceInfoFactory + PriceInfoFactory $priceInfoFactory, + ValueFactory $valueFactory ) { $this->storeManager = $storeManager; $this->priceInfoFactory = $priceInfoFactory; + $this->valueFactory = $valueFactory; } /** @@ -44,8 +60,20 @@ public function __construct( * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) : array - { + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + if (!isset($value['model'])) { + return null; + } + + /** @var Product $product */ + $product = $value['model']; + $priceInfo = $this->priceInfoFactory->create($product); /** @var \Magento\Catalog\Pricing\Price\FinalPriceInterface $finalPrice */ $finalPrice = $priceInfo->getPrice(FinalPrice::PRICE_CODE); @@ -53,13 +81,17 @@ public function format(Product $product, array $productData = []) : array $maximalPriceAmount = $finalPrice->getMaximalPrice(); $regularPriceAmount = $priceInfo->getPrice(RegularPrice::PRICE_CODE)->getAmount(); - $productData['price'] = [ + $prices = [ 'minimalPrice' => $this->createAdjustmentsArray($priceInfo->getAdjustments(), $minimalPriceAmount), 'regularPrice' => $this->createAdjustmentsArray($priceInfo->getAdjustments(), $regularPriceAmount), 'maximalPrice' => $this->createAdjustmentsArray($priceInfo->getAdjustments(), $maximalPriceAmount) ]; - return $productData; + $result = function () use ($prices) { + return $prices; + }; + + return $this->valueFactory->create($result); } /** diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php new file mode 100644 index 0000000000000..426d558caca1d --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php @@ -0,0 +1,79 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\ProductLink\Link; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; + +/** + * Format the product links information to conform to GraphQL schema representation + * + * {@inheritdoc} + */ +class ProductLinks implements ResolverInterface +{ + /** + * @var string[] + */ + private $linkTypes = ['related', 'upsell', 'crosssell']; + + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param ValueFactory $valueFactory + */ + public function __construct(ValueFactory $valueFactory) + { + $this->valueFactory = $valueFactory; + } + + /** + * Format product links data to conform to GraphQL schema + * + * {@inheritdoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + if (!isset($value['model'])) { + return null; + } + + /** @var Product $product */ + $product = $value['model']; + + $links = null; + if ($product->getProductLinks()) { + $links = []; + /** @var Link $productLink */ + foreach ($product->getProductLinks() as $productLink) { + if (in_array($productLink->getLinkType(), $this->linkTypes)) { + $links[] = $productLink->getData(); + } + } + } + + $result = function () use ($links) { + return $links; + }; + + return $this->valueFactory->create($result); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php new file mode 100644 index 0000000000000..6d3e06a8d0ee8 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php @@ -0,0 +1,72 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\TierPrice; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; + +/** + * Format a product's tier price information to conform to GraphQL schema representation + * + * {@inheritdoc} + */ +class TierPrices implements ResolverInterface +{ + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param ValueFactory $valueFactory + */ + public function __construct(ValueFactory $valueFactory) + { + $this->valueFactory = $valueFactory; + } + + /** + * Format product's tier price data to conform to GraphQL schema + * + * {@inheritdoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + if (!isset($value['model'])) { + return null; + } + + /** @var Product $product */ + $product = $value['model']; + + $tierPrices = null; + if ($product->getTierPrices()) { + $tierPrices = []; + /** @var TierPrice $tierPrice */ + foreach ($product->getTierPrices() as $tierPrice) { + $tierPrices[] = $tierPrice->getData(); + } + } + + $result = function () use ($tierPrices) { + return $tierPrices; + }; + + return $this->valueFactory->create($result); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php index bf832ba5830dc..86b4c74c7e037 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php @@ -77,9 +77,9 @@ public function resolve( __("'search' or 'filter' input argument is required.") ); } elseif (isset($args['search'])) { - $searchResult = $this->searchQuery->getResult($searchCriteria); + $searchResult = $this->searchQuery->getResult($searchCriteria, $info); } else { - $searchResult = $this->filterQuery->getResult($searchCriteria); + $searchResult = $this->filterQuery->getResult($searchCriteria, $info); } //possible division by 0 diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Attributes/Collection.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Attributes/Collection.php new file mode 100644 index 0000000000000..80610e8087d48 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Attributes/Collection.php @@ -0,0 +1,97 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Products\Attributes; + +use GraphQL\Language\AST\FieldNode; +use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory as AttributeCollectionFactory; +use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection as AttributeCollection; +use Magento\Eav\Model\Attribute; + +/** + * Gather all eav and custom attributes to use in a GraphQL schema for products + */ +class Collection +{ + /** + * @var AttributeCollectionFactory + */ + private $collectionFactory; + + /** + * @var AttributeCollection + */ + private $collection = null; + + /** + * @param AttributeCollectionFactory $collectionFactory + */ + public function __construct(AttributeCollectionFactory $collectionFactory) + { + $this->collectionFactory = $collectionFactory; + } + + /** + * Return all custom and eav attributes configured for products. + * + * @return AttributeCollection + */ + public function getAttributes() : AttributeCollection + { + if (!$this->collection) { + $this->collection = $this->collectionFactory->create(); + $this->collection->addFieldToFilter('is_user_defined', '1'); + $this->collection->addFieldToFilter('attribute_code', ['neq' => 'cost']); + } + + return $this->collection->load(); + } + + /** + * Find EAV names based on passed in field names from GraphQL request, match to all known EAV attribute codes. + * + * @param string[] $fieldNames + * @return string[] + */ + public function getRequestAttributes(array $fieldNames) : array + { + $attributes = $this->getAttributes(); + $attributeNames = []; + /** @var Attribute $attribute */ + foreach ($attributes as $attribute) { + $attributeNames[] = $attribute->getAttributeCode(); + } + + $matchedAttributes = []; + foreach ($fieldNames as $name) { + if (!in_array($name, $attributeNames)) { + continue; + } + + $matchedAttributes[] = $name; + } + + return $matchedAttributes; + + foreach ($info->fieldNodes as $node) { + if ($node->name->value !== 'products') { + continue; + } + foreach ($node->selectionSet->selections as $selection) { + if ($selection->name->value !== 'items') { + continue; + } + + foreach ($selection->selectionSet->selections as $itemSelections) { + if (in_array($itemSelections->name->value, $attributeCodes)) { + $collection->addAttributeToSelect($selection->name->value); + } + } + } + } + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php index e0766319e04f1..2a5282c63613e 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php @@ -9,7 +9,6 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product as ProductDataProvider; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; use Magento\Framework\Api\SearchCriteriaBuilder; /** @@ -22,11 +21,6 @@ class Product */ private $productDataProvider; - /** - * @var FormatterInterface - */ - private $formatter; - /** * @var SearchCriteriaBuilder */ @@ -42,18 +36,20 @@ class Product */ private $productList = []; + /** + * @var string[] + */ + private $attributeCodes = []; + /** * @param ProductDataProvider $productDataProvider - * @param FormatterInterface $formatter * @param SearchCriteriaBuilder $searchCriteriaBuilder */ public function __construct( ProductDataProvider $productDataProvider, - FormatterInterface $formatter, SearchCriteriaBuilder $searchCriteriaBuilder ) { $this->productDataProvider = $productDataProvider; - $this->formatter = $formatter; $this->searchCriteriaBuilder = $searchCriteriaBuilder; } @@ -65,7 +61,11 @@ public function __construct( */ public function addProductSku(string $sku) : void { - if (!in_array($sku, $this->productSkus)) { + if (!in_array($sku, $this->productSkus) && !empty($this->productList)) { + $this->productList = []; + $this->productSkus = []; + $this->productSkus[] = $sku; + } elseif (!in_array($sku, $this->productSkus)) { $this->productSkus[] = $sku; } } @@ -79,14 +79,27 @@ public function addProductSku(string $sku) : void public function addProductSkus(array $skus) : void { foreach ($skus as $sku) { - if (in_array($sku, $this->productSkus)) { - continue; + if (!in_array($sku, $this->productSkus) && !empty($this->productList)) { + $this->productList = []; + $this->productSkus = []; + $this->productSkus[] = $sku; + } elseif (!in_array($sku, $this->productSkus)) { + $this->productSkus[] = $sku; } - - $this->productSkus[] = $sku; } } + /** + * Add attributes to collection filter + * + * @param array $attributeCodes + * @return void + */ + public function addEavAttributes(array $attributeCodes) : void + { + $this->attributeCodes = array_replace($this->attributeCodes, $attributeCodes); + } + /** * Get product from result set. * @@ -116,11 +129,11 @@ private function fetch() : array } $this->searchCriteriaBuilder->addFilter(ProductInterface::SKU, $this->productSkus, 'in'); - $result = $this->productDataProvider->getList($this->searchCriteriaBuilder->create()); + $result = $this->productDataProvider->getList($this->searchCriteriaBuilder->create(), $this->attributeCodes); /** @var \Magento\Catalog\Model\Product $product */ foreach ($result->getItems() as $product) { - $this->productList[$product->getSku()] = $this->formatter->format($product); + $this->productList[$product->getSku()] = ['model' => $product]; } return $this->productList; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php index 6d508b9ec1413..0e6094d700ed6 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php @@ -58,34 +58,37 @@ public function __construct( } /** - * Gets list of product data with full data set + * Gets list of product data with full data set. Adds eav attributes to result set from passed in array * * @param SearchCriteriaInterface $searchCriteria + * @param string[] $attributes * @return SearchResultsInterface */ - public function getList(SearchCriteriaInterface $searchCriteria) : SearchResultsInterface + public function getList(SearchCriteriaInterface $searchCriteria, array $attributes = []) : SearchResultsInterface { /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */ $collection = $this->collectionFactory->create(); $this->joinProcessor->process($collection); - $collection->addAttributeToSelect('*'); + foreach ($attributes as $attributeCode) { + $collection->addAttributeToSelect($attributeCode); + } $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner'); $collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner'); $this->collectionProcessor->process($searchCriteria, $collection); - + $count = $collection->getSelectCountSql()->query(); + $collection->addPriceData(); + $collection->addWebsiteNamesToResult(); + $collection->addTaxPercents(); + $collection->addWebsiteNamesToResult(); $collection->load(); + // Methods that perform extra fetches $collection->addCategoryIds(); - $collection->addFinalPrice(); $collection->addMediaGalleryData(); - $collection->addMinimalPrice(); - $collection->addPriceData(); - $collection->addWebsiteNamesToResult(); $collection->addOptionsToResult(); - $collection->addTaxPercents(); - $collection->addWebsiteNamesToResult(); + $searchResult = $this->searchResultsFactory->create(); $searchResult->setSearchCriteria($searchCriteria); $searchResult->setItems($collection->getItems()); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BaseModelData.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BaseModelData.php deleted file mode 100644 index 8ea689ca99214..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/BaseModelData.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; - -use Magento\Catalog\Model\Product; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; - -/** - * Grabs the data from the product - */ -class BaseModelData implements FormatterInterface -{ - /** - * Get data from product - * - * {@inheritdoc} - */ - public function format(Product $product, array $productData = []) : array - { - return $product->getData(); - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/CustomAttributes.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/CustomAttributes.php deleted file mode 100644 index c39b3890da280..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/CustomAttributes.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; - -use Magento\Catalog\Model\Product; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; - -/** - * Populates the custom attributes - */ -class CustomAttributes implements FormatterInterface -{ - /** - * Populate the defined custom attributes - * - * {@inheritdoc} - */ - public function format(Product $product, array $productData = []) : array - { - foreach ($product->getCustomAttributes() as $customAttribute) { - if (!isset($productData[$customAttribute->getAttributeCode()])) { - $productData[$customAttribute->getAttributeCode()] = $customAttribute->getValue(); - } - } - return $productData; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/EntityIdToId.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/EntityIdToId.php deleted file mode 100644 index 395feee48ded6..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/EntityIdToId.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; - -use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Catalog\Model\Product; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; -use Magento\Framework\EntityManager\MetadataPool; - -/** - * Fixed the id related data in the product data - */ -class EntityIdToId implements FormatterInterface -{ - /** - * @var MetadataPool - */ - private $metadataPool; - - /** - * @param MetadataPool $metadataPool - */ - public function __construct(MetadataPool $metadataPool) - { - $this->metadataPool = $metadataPool; - } - - /** - * Fix entity id data by converting it to an id key - * - * {@inheritdoc} - */ - public function format(Product $product, array $productData = []) : array - { - $productData['id'] = $product->getData( - $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField() - ); - - return $productData; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/MediaGalleryEntries.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/MediaGalleryEntries.php deleted file mode 100644 index 572649123a9b2..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/MediaGalleryEntries.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; - -use Magento\Catalog\Model\Product; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; - -/** - * Format a product's media gallery information to conform to GraphQL schema representation - */ -class MediaGalleryEntries implements FormatterInterface -{ - /** - * Format product's media gallery entry data to conform to GraphQL schema - * - * {@inheritdoc} - */ - public function format(Product $product, array $productData = []) : array - { - if (!empty($product->getMediaGalleryEntries())) { - foreach ($product->getMediaGalleryEntries() as $key => $entry) { - $productData['media_gallery_entries'][$key] = $entry->getData(); - if ($entry->getExtensionAttributes() && $entry->getExtensionAttributes()->getVideoContent()) { - $productData['media_gallery_entries'][$key]['video_content'] - = $entry->getExtensionAttributes()->getVideoContent()->getData(); - } - } - } - - return $productData; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/NewFromTo.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/NewFromTo.php deleted file mode 100644 index 5033893c23d87..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/NewFromTo.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; - -use Magento\Catalog\Model\Product; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; - -/** - * Format the new from and to typo of legacy fields news_from_date and news_to_date - */ -class NewFromTo implements FormatterInterface -{ - /** - * Transfer data from legacy news_from_date and news_to_date to new names corespondent fields - * - * {@inheritdoc} - */ - public function format(Product $product, array $productData = []) : array - { - if ($product->getData('news_from_date')) { - $productData['new_from_date'] = $product->getData('news_from_date'); - } - - if ($product->getData('news_to_date')) { - $productData['new_to_date'] = $product->getData('news_to_date'); - } - - return $productData; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Options.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Options.php deleted file mode 100644 index 0917335c4535f..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/Options.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; - -use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\Product\Option; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; - -/** - * Format a product's option information to conform to GraphQL schema representation - */ -class Options implements FormatterInterface -{ - /** - * Format product's option data to conform to GraphQL schema - * - * {@inheritdoc} - */ - public function format(Product $product, array $productData = []) : array - { - if (!empty($product->getOptions())) { - /** @var Option $option */ - foreach ($product->getOptions() as $key => $option) { - unset($productData['options'][$key]); - $productData['options'][$key] = $option->getData(); - $productData['options'][$key]['required'] = $option->getIsRequire(); - $productData['options'][$key]['product_sku'] = $option->getProductSku(); - - $values = $option->getValues() ?: []; - /** @var Option\Value $value */ - foreach ($values as $valueKey => $value) { - $productData['options'][$key]['value'][$valueKey] = $value->getData(); - $productData['options'][$key]['value'][$valueKey]['price_type'] - = $value->getPriceType() !== null ? strtoupper($value->getPriceType()) : 'DYNAMIC'; - } - - if (empty($values)) { - $productData['options'][$key]['value'] = $option->getData(); - $productData['options'][$key]['value']['price_type'] - = $option->getPriceType() !== null ? strtoupper($option->getPriceType()) : 'DYNAMIC'; - } - } - } - - return $productData; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php deleted file mode 100644 index 486c3c66da1da..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; - -use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\ProductLink\Link; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; - -/** - * Format the product links information to conform to GraphQL schema representation - */ -class ProductLinks implements FormatterInterface -{ - /** - * @var string[] - */ - private $linkTypes = ['related', 'upsell', 'crosssell']; - - /** - * Format product links data to conform to GraphQL schema - * - * {@inheritdoc} - */ - public function format(Product $product, array $productData = []) : array - { - $productLinks = $product->getProductLinks(); - if ($productLinks) { - /** @var Link $productLink */ - foreach ($productLinks as $productLinkKey => $productLink) { - if (in_array($productLink->getLinkType(), $this->linkTypes)) { - $productData['product_links'][$productLinkKey] = $productLink->getData(); - } - } - } else { - $productData['product_links'] = null; - } - - return $productData; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/TierPrices.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/TierPrices.php deleted file mode 100644 index b724c63578dc2..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/TierPrices.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; - -use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\Product\TierPrice; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; - -/** - * Format a product's tier price information to conform to GraphQL schema representation - */ -class TierPrices implements FormatterInterface -{ - /** - * Format product's tier price data to conform to GraphQL schema - * - * {@inheritdoc} - */ - public function format(Product $product, array $productData = []) : array - { - $tierPrices = $product->getTierPrices(); - if ($tierPrices) { - /** @var TierPrice $tierPrice */ - foreach ($tierPrices as $tierPrice) { - $productData['tier_prices'][] = $tierPrice->getData(); - } - } else { - $productData['tier_prices'] = null; - } - - return $productData; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterComposite.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterComposite.php deleted file mode 100644 index 66ef1f9287a95..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterComposite.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product; - -use Magento\Catalog\Model\Product; - -/** - * Class implementing the composite pattern on @see FormatterInterface::format method - */ -class FormatterComposite implements FormatterInterface -{ - - /** - * @var FormatterInterface[] - */ - private $formatterInstances = []; - - /** - * @param FormatterInterface[] $formatterInstances - */ - public function __construct(array $formatterInstances) - { - $this->formatterInstances = $formatterInstances; - } - - /** - * Format single product data from object to an array - * - * {@inheritdoc} - */ - public function format(Product $product, array $productData = []) : array - { - foreach ($this->formatterInstances as $formatterInstance) { - $productData = $formatterInstance->format($product, $productData); - } - - return $productData; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterInterface.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterInterface.php deleted file mode 100644 index bff07d508f161..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/FormatterInterface.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product; - -use Magento\Catalog\Model\Product; - -/** - * Transforms data of a product to its GraphQL type format" - */ -interface FormatterInterface -{ - /** - * Format single product data to GraphQl type structure - * - * @param Product $product - * @param array $productData - * @return array - */ - public function format(Product $product, array $productData = []) : array; -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php index 1c05346ab0fe5..58f3a6c5dc2b3 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php @@ -7,12 +7,12 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Products\Query; +use GraphQL\Type\Definition\ResolveInfo; +use Magento\CatalogGraphQl\Model\Resolver\Products\Attributes\Collection; use Magento\Framework\Api\SearchCriteriaInterface; -use Magento\Framework\GraphQl\Query\PostFetchProcessorInterface; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product; use Magento\CatalogGraphQl\Model\Resolver\Products\SearchResult; use Magento\CatalogGraphQl\Model\Resolver\Products\SearchResultFactory; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; /** * Retrieve filtered product data based off given search criteria in a format that GraphQL can interpret. @@ -30,76 +30,70 @@ class Filter private $productDataProvider; /** - * @var FormatterInterface + * @var Collection */ - private $formatter; - - /** - * @var PostFetchProcessorInterface[] - */ - private $postProcessors; + private $collection; /** * @param SearchResultFactory $searchResultFactory * @param Product $productDataProvider - * @param FormatterInterface $formatter - * @param PostFetchProcessorInterface[] $postProcessors + * @param Collection $collection */ public function __construct( SearchResultFactory $searchResultFactory, Product $productDataProvider, - FormatterInterface $formatter, - array $postProcessors = [] + Collection $collection ) { $this->searchResultFactory = $searchResultFactory; $this->productDataProvider = $productDataProvider; - $this->postProcessors = $postProcessors; - $this->formatter = $formatter; + $this->collection = $collection; } /** * Filter catalog product data based off given search criteria * * @param SearchCriteriaInterface $searchCriteria + * @param ResolveInfo $info * @return SearchResult */ - public function getResult(SearchCriteriaInterface $searchCriteria) : SearchResult + public function getResult(SearchCriteriaInterface $searchCriteria, ResolveInfo $info) : SearchResult { - $realPageSize = $searchCriteria->getPageSize(); - $realCurrentPage = $searchCriteria->getCurrentPage(); - // Current page must be set to 0 and page size to max for search to grab all ID's as temporary workaround for - // inaccurate search - $searchCriteria->setPageSize(PHP_INT_MAX); - $searchCriteria->setCurrentPage(1); - $products = $this->productDataProvider->getList($searchCriteria); + $fields = $this->getProductFields($info); + $matchedFields = $this->collection->getRequestAttributes($fields); + $products = $this->productDataProvider->getList($searchCriteria, $matchedFields); $productArray = []; - $searchCriteria->setPageSize($realPageSize); - $searchCriteria->setCurrentPage($realCurrentPage); - $paginatedProducts = $this->paginateList($products->getItems(), $searchCriteria); /** @var \Magento\Catalog\Model\Product $product */ - foreach ($paginatedProducts as $product) { - $productArray[] = $this->formatter->format($product); - } - - foreach ($this->postProcessors as $postProcessor) { - $productArray = $postProcessor->process($productArray); + foreach ($products->getItems() as $product) { + $productArray[] = ['model' => $product]; } return $this->searchResultFactory->create($products->getTotalCount(), $productArray); } /** - * Paginate an array of Ids that get pulled back in search based off search criteria and total count. + * Return field names for all requested product fields. * - * @param array $ids - * @param SearchCriteriaInterface $searchCriteria - * @return int[] + * @param ResolveInfo $info + * @return string[] */ - private function paginateList(array $ids, SearchCriteriaInterface $searchCriteria) : array + private function getProductFields(ResolveInfo $info) { - $length = $searchCriteria->getPageSize(); - // Search starts pages from 0 - $offset = $length * ($searchCriteria->getCurrentPage() - 1); - return array_slice($ids, $offset, $length); + $fieldNames = []; + foreach ($info->fieldNodes as $node) { + if ($node->name->value !== 'products') { + continue; + } + foreach ($node->selectionSet->selections as $selection) { + if ($selection->name->value !== 'items') { + continue; + } + + foreach ($selection->selectionSet->selections as $itemSelection) { + $fieldNames[] = $itemSelection->name->value; + } + } + } + + return $fieldNames; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php index 75db4332d6ae7..3a412ab6d3453 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php @@ -7,6 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Products\Query; +use GraphQL\Type\Definition\ResolveInfo; use Magento\Framework\Api\Search\SearchCriteriaInterface; use Magento\CatalogGraphQl\Model\Resolver\Products\SearchCriteria\Helper\Filter as FilterHelper; use Magento\CatalogGraphQl\Model\Resolver\Products\SearchResult; @@ -62,7 +63,7 @@ public function __construct( * @param SearchCriteriaInterface $searchCriteria * @return SearchResult */ - public function getResult(SearchCriteriaInterface $searchCriteria) : SearchResult + public function getResult(SearchCriteriaInterface $searchCriteria, ResolveInfo $info) : SearchResult { $realPageSize = $searchCriteria->getPageSize(); $realCurrentPage = $searchCriteria->getCurrentPage(); @@ -77,24 +78,26 @@ public function getResult(SearchCriteriaInterface $searchCriteria) : SearchResul $ids[$item->getId()] = null; $searchIds[] = $item->getId(); } - $searchCriteria->setPageSize($realPageSize); - $searchCriteria->setCurrentPage($realCurrentPage); $filter = $this->filterHelper->generate('entity_id', 'in', $searchIds); $searchCriteria = $this->filterHelper->remove($searchCriteria, 'search_term'); $searchCriteria = $this->filterHelper->add($searchCriteria, $filter); - $searchResult = $this->filterQuery->getResult($searchCriteria); + $searchResult = $this->filterQuery->getResult($searchCriteria, $info); + + $searchCriteria->setPageSize($realPageSize); + $searchCriteria->setCurrentPage($realCurrentPage); + $paginatedProducts = $this->paginateList($searchResult->getProductsSearchResult(), $searchCriteria); $products = []; if (!isset($searchCriteria->getSortOrders()[0])) { - foreach ($searchResult->getProductsSearchResult() as $product) { + foreach ($paginatedProducts as $product) { if (in_array($product['id'], $searchIds)) { $ids[$product['id']] = $product; } } $products = array_filter($ids); } else { - foreach ($searchResult->getProductsSearchResult() as $product) { + foreach ($paginatedProducts as $product) { if (in_array($product['id'], $searchIds)) { $products[] = $product; } @@ -103,4 +106,19 @@ public function getResult(SearchCriteriaInterface $searchCriteria) : SearchResul return $this->searchResultFactory->create($searchResult->getTotalCount(), $products); } + + /** + * Paginate an array of Ids that get pulled back in search based off search criteria and total count. + * + * @param array $products + * @param SearchCriteriaInterface $searchCriteria + * @return int[] + */ + private function paginateList(array $products, SearchCriteriaInterface $searchCriteria) : array + { + $length = $searchCriteria->getPageSize(); + // Search starts pages from 0 + $offset = $length * ($searchCriteria->getCurrentPage() - 1); + return array_slice($products, $offset, $length); + } } diff --git a/app/code/Magento/CatalogGraphQl/etc/di.xml b/app/code/Magento/CatalogGraphQl/etc/di.xml index b7338139e5b9f..2e8d9b2b15690 100644 --- a/app/code/Magento/CatalogGraphQl/etc/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/di.xml @@ -6,7 +6,6 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <preference for="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface" type="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterComposite" /> <preference for="Magento\Framework\GraphQl\Argument\AstConverterInterface" type="Magento\CatalogGraphQl\Model\Resolver\Products\FilterArgument\AstConverter" /> <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product"> <arguments> diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql.xml b/app/code/Magento/CatalogGraphQl/etc/graphql.xml index d6fe68a540890..f9606be7bcbf8 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql.xml @@ -231,7 +231,7 @@ <field xsi:type="ScalarOutputField" name="customer_group_id" type="String" description="The ID of the customer group"/> </type> <type xsi:type="OutputInterface" name="ProductInterface" typeResolver="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> - <field xsi:type="ScalarOutputField" name="id" type="Int" description="The ID number assigned to the product."/> + <field xsi:type="ScalarOutputField" name="id" type="Int" resolver="Magento\CatalogGraphQl\Model\Resolver\Product\EntityIdToId" description="The ID number assigned to the product."/> <field xsi:type="ScalarOutputField" name="name" type="String" description="The product name. Customers use this name to identify the product."/> <field xsi:type="ScalarOutputField" name="sku" type="String" description="A number or code assigned to a product to identify the product, options, price, and manufacturer."/> <field xsi:type="ScalarOutputField" name="description" type="String" description="A detailed information about the product. The value can include simple HTML tags."/> @@ -246,8 +246,8 @@ <field xsi:type="ScalarOutputField" name="image" type="String" description="The relative path for the main image on the product page."/> <field xsi:type="ScalarOutputField" name="small_image" type="String" description="The file name of a small image, which is used on catalog pages."/> <field xsi:type="ScalarOutputField" name="thumbnail" type="String" description="The file name of a thumbnail image"/> - <field xsi:type="ScalarOutputField" name="new_from_date" type="String" description="The beginning date for new product listings, and determines if the product is featured as a new product. Note: The input attribute name is 'news_from_date'."/> - <field xsi:type="ScalarOutputField" name="new_to_date" type="String" description="The end date for new product listings. Note: The input attribute name is 'news_to_date'."/> + <field xsi:type="ScalarOutputField" name="new_from_date" resolver="Magento\CatalogGraphQl\Model\Resolver\Product\NewFromTo" type="String" description="The beginning date for new product listings, and determines if the product is featured as a new product. Note: The input attribute name is 'news_from_date'."/> + <field xsi:type="ScalarOutputField" name="new_to_date" resolver="Magento\CatalogGraphQl\Model\Resolver\Product\NewFromTo" type="String" description="The end date for new product listings. Note: The input attribute name is 'news_to_date'."/> <field xsi:type="ScalarOutputField" name="tier_price" type="Float" description="The price when tier pricing is in effect and the items purchased threshold has been reached."/> <field xsi:type="ScalarOutputField" name="custom_design" type="String" description="A theme that can be applied to the product page."/> <field xsi:type="ScalarOutputField" name="custom_design_from" type="String" description="The beginning date when a theme is applied to the product page."/> @@ -265,18 +265,18 @@ <field xsi:type="ScalarOutputField" name="country_of_manufacture" type="String" description="The product's country of origin"/> <field xsi:type="ScalarOutputField" name="type_id" type="String" description="One of 'simple', 'virtual', 'bundle', 'downloadable','grouped', or 'configurable'"/> <field xsi:type="ScalarArrayOutputField" name="website_ids" itemType="Int" description="An array of website IDs in which the product is available."/> - <field xsi:type="ObjectArrayOutputField" name="category_links" itemType="ProductCategoryLinks" description="An array that contains links to categories the product is assigned to."/> - <field xsi:type="ObjectArrayOutputField" name="product_links" itemType="ProductLinksInterface" description="An array that contains information about products that are related to the current product."/> - <field xsi:type="ObjectArrayOutputField" name="media_gallery_entries" itemType="MediaGalleryEntry" description="An array that contains information about the images and video assigned to this product."/> - <field xsi:type="ObjectArrayOutputField" name="tier_prices" itemType="ProductTierPrices" description="An array that defines tier prices for the item."/> - <field xsi:type="ObjectOutputField" name="price" type="ProductPrices" description="The price of the item, including the value and the currency code."/> + <field xsi:type="ObjectArrayOutputField" name="category_links" itemType="ProductCategoryLinks" resolver="Magento\CatalogGraphQl\Model\Resolver\Product\CategoryLinks" description="An array that contains links to categories the product is assigned to."/> + <field xsi:type="ObjectArrayOutputField" name="product_links" itemType="ProductLinksInterface" resolver="Magento\CatalogGraphQl\Model\Resolver\Product\ProductLinks" description="An array that contains information about products that are related to the current product."/> + <field xsi:type="ObjectArrayOutputField" name="media_gallery_entries" itemType="MediaGalleryEntry" resolver="Magento\CatalogGraphQl\Model\Resolver\Product\MediaGalleryEntries" description="An array that contains information about the images and video assigned to this product."/> + <field xsi:type="ObjectArrayOutputField" name="tier_prices" itemType="ProductTierPrices" resolver="Magento\CatalogGraphQl\Model\Resolver\Product\TierPrices" description="An array that defines tier prices for the item."/> + <field xsi:type="ObjectOutputField" name="price" type="ProductPrices" resolver="Magento\CatalogGraphQl\Model\Resolver\Product\Price" description="The price of the item, including the value and the currency code."/> <field xsi:type="ScalarOutputField" name="gift_message_available" type="String" description="Indicates whether a gift message is available."/> </type> <type xsi:type="OutputInterface" name="PhysicalProductInterface" typeResolver="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> <field xsi:type="ScalarOutputField" name="weight" type="Float" description="The weight of a physical product"/> </type> <type xsi:type="OutputInterface" name="CustomizableProductInterface" typeResolver="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> - <field xsi:type="ObjectArrayOutputField" name="options" itemType="CustomizableOptionInterface" description="An array containing information about the customizable options for a product"/> + <field xsi:type="ObjectArrayOutputField" name="options" itemType="CustomizableOptionInterface" resolver="Magento\CatalogGraphQl\Model\Resolver\Product\Options" description="An array containing information about the customizable options for a product"/> </type> <type xsi:type="OutputInterface" name="CustomizableOptionInterface" typeResolver="Magento\CatalogGraphQl\Model\CustomizableOptionTypeResolver"> <field xsi:type="ScalarOutputField" name="title" type="String" description="The displayed name of the option"/> diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index 32717bfc151c4..0e16486133f73 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -6,21 +6,6 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterComposite"> - <arguments> - <argument name="formatterInstances" xsi:type="array"> - <item name="baseModelData" xsi:type="object">Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter\BaseModelData</item> - <item name="customAttributes" xsi:type="object">Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter\CustomAttributes</item> - <item name="entityIdToId" xsi:type="object">Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter\EntityIdToId</item> - <item name="mediaGalleryEntries" xsi:type="object">Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter\MediaGalleryEntries</item> - <item name="options" xsi:type="object">Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter\Options</item> - <item name="price" xsi:type="object">Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter\Price</item> - <item name="tierPrices" xsi:type="object">Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter\TierPrices</item> - <item name="newFromTo" xsi:type="object">Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter\NewFromTo</item> - <item name="productLinks" xsi:type="object">Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter\ProductLinks</item> - </argument> - </arguments> - </type> <type name="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> <arguments> <argument name="productTypeNameResolvers" xsi:type="array"> diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php deleted file mode 100644 index 3e39379f6eec1..0000000000000 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Plugin/Model/Resolver/Products/DataProvider/ProductPlugin.php +++ /dev/null @@ -1,149 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\ConfigurableProductGraphQl\Model\Plugin\Model\Resolver\Products\DataProvider; - -use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\ConfigurableProduct\Model\Product\Type\Configurable; -use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\Collection - as AttributeCollection; -use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection as ProductCollection; -use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\Framework\Api\SearchResultsInterface; -use Magento\Framework\Api\SearchResultsInterfaceFactory; -use Magento\Framework\DataObject; -use Magento\Framework\EntityManager\MetadataPool; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product; -use Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute; - -/** - * Fetch configurable product children data and add to final result of product collection. - */ -class ProductPlugin -{ - /** - * @var Configurable - */ - private $configurable; - - /** - * @var AttributeCollection - */ - private $attributeCollection; - - /** - * @var ProductCollection - */ - private $productCollection; - - /** - * @var ProductRepositoryInterface - */ - private $productRepository; - - /** - * @var SearchCriteriaBuilder - */ - private $searchCriteriaBuilder; - - /** - * @var MetadataPool - */ - private $metadataPool; - - /** - * ProductPlugin constructor. - * - * @param Configurable $configurable - * @param AttributeCollection $attributeCollection - * @param ProductCollection $productCollection - * @param ProductRepositoryInterface $productRepository - * @param SearchCriteriaBuilder $searchCriteriaBuilder - * @param MetadataPool $metadataPool - */ - public function __construct( - Configurable $configurable, - AttributeCollection $attributeCollection, - ProductCollection $productCollection, - ProductRepositoryInterface $productRepository, - SearchCriteriaBuilder $searchCriteriaBuilder, - MetadataPool $metadataPool - ) { - $this->configurable = $configurable; - $this->attributeCollection = $attributeCollection; - $this->productCollection = $productCollection; - $this->productRepository = $productRepository; - $this->searchCriteriaBuilder = $searchCriteriaBuilder; - $this->metadataPool = $metadataPool; - } - - /** - * Intercept GraphQLCatalog getList, and add any necessary configurable fields - * - * @param Product $subject - * @param SearchResultsInterface $result - * @return SearchResultsInterface - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function afterGetList(Product $subject, SearchResultsInterface $result) : SearchResultsInterface - { - $processConfigurableData = false; - /** @var ProductInterface $product */ - foreach ($result->getItems() as $product) { - if ($product->getTypeId() === Configurable::TYPE_CODE) { - $this->productCollection->setProductFilter($product); - $this->attributeCollection->setProductFilter($product); - $processConfigurableData = true; - } - } - - if ($processConfigurableData) { - /** @var \Magento\Catalog\Model\Product[] $children */ - $children = $this->productCollection->getItems(); - /** @var Attribute[] $attributes */ - $attributes = $this->attributeCollection->getItems(); - $result = $this->addConfigurableData($result, $children, $attributes); - } - - return $result; - } - - /** - * Add configurable data to any configurable products in result set - * - * @param SearchResultsInterface $result - * @param DataObject[] $children - * @param DataObject[] $attributes - * @return SearchResultsInterface - */ - private function addConfigurableData($result, $children, $attributes) - { - $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); - foreach ($result->getItems() as $product) { - if ($product->getTypeId() === Configurable::TYPE_CODE) { - $extensionAttributes = $product->getExtensionAttributes(); - $childrenIds = []; - foreach ($children as $child) { - if ($child->getParentId() === $product->getData($linkField)) { - $childrenIds[] = $child->getId(); - } - } - $productAttributes = []; - foreach ($attributes as $attribute) { - if ($attribute->getProductId() === $product->getId()) { - $productAttributes[] = $attribute; - } - } - $extensionAttributes->setConfigurableProductLinks($childrenIds); - $extensionAttributes->setConfigurableProductOptions($productAttributes); - $product->setExtensionAttributes($extensionAttributes); - } - } - - return $result; - } -} diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ConfigurableOptions.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ConfigurableOptions.php deleted file mode 100644 index d8fb3e8432ed4..0000000000000 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ConfigurableOptions.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\ConfigurableProductGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; - -use Magento\Catalog\Model\Product; -use Magento\ConfigurableProduct\Model\Product\Type\Configurable; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; - -/** - * Post formatting to continue formatting data for configurable type products - */ -class ConfigurableOptions implements FormatterInterface -{ - /** - * @var Configurable - */ - private $configurableData; - - /** - * @param Configurable $configurableData - */ - public function __construct(Configurable $configurableData) - { - $this->configurableData = $configurableData; - } - - /** - * Add configurable links and options to configurable types - * - * {@inheritdoc} - */ - public function format(Product $product, array $productData = []) : array - { - if ($product->getTypeId() === Configurable::TYPE_CODE) { - $extensionAttributes = $product->getExtensionAttributes(); - $productData['configurable_product_options'] = $extensionAttributes->getConfigurableProductOptions(); - $productData['configurable_product_links'] = $extensionAttributes->getConfigurableProductLinks(); - /** @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute $option */ - foreach ($productData['configurable_product_options'] as $optionKey => $option) { - $productData['configurable_product_options'][$optionKey]['attribute_code'] - = $option->getProductAttribute()->getAttributeCode(); - } - } - - return $productData; - } -} diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/Query/ConfigurableProductPostProcessor.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/Query/ConfigurableProductPostProcessor.php deleted file mode 100644 index aaeb79d78e0d9..0000000000000 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Products/Query/ConfigurableProductPostProcessor.php +++ /dev/null @@ -1,116 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\ConfigurableProductGraphQl\Model\Resolver\Products\Query; - -use Magento\ConfigurableProduct\Model\Product\Type\Configurable; -use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; -use Magento\Framework\GraphQl\Query\PostFetchProcessorInterface; - -/** - * Retrieves simple product data for child products and formats configurable data - */ -class ConfigurableProductPostProcessor implements PostFetchProcessorInterface -{ - /** - * @var SearchCriteriaBuilder - */ - private $searchCriteriaBuilder; - - /** - * @var Product - */ - private $productDataProvider; - - /** - * @var \Magento\Catalog\Model\ResourceModel\Product - */ - private $productResource; - - /** - * @var FormatterInterface - */ - private $formatter; - - /** - * @param SearchCriteriaBuilder $searchCriteriaBuilder - * @param Product $productDataProvider - * @param \Magento\Catalog\Model\ResourceModel\Product $productResource - * @param FormatterInterface $formatter - */ - public function __construct( - SearchCriteriaBuilder $searchCriteriaBuilder, - Product $productDataProvider, - \Magento\Catalog\Model\ResourceModel\Product $productResource, - FormatterInterface $formatter - ) { - $this->searchCriteriaBuilder = $searchCriteriaBuilder; - $this->productDataProvider = $productDataProvider; - $this->productResource = $productResource; - $this->formatter = $formatter; - } - - /** - * Process all configurable product data, including adding simple product data and formatting relevant attributes. - * - * @param array $resultData - * @return array - */ - public function process(array $resultData) : array - { - $childrenIds = []; - foreach ($resultData as $key => $product) { - if (isset($product['type_id']) && $product['type_id'] === Configurable::TYPE_CODE) { - $formattedChildIds = []; - if (isset($product['configurable_product_links'])) { - foreach ($product['configurable_product_links'] as $childId) { - $childrenIds[] = (int)$childId; - $formattedChildIds[$childId] = null; - } - } - $resultData[$key]['configurable_product_links'] = $formattedChildIds; - } - } - - $this->searchCriteriaBuilder->addFilter('entity_id', $childrenIds, 'in'); - $childProducts = $this->productDataProvider->getList($this->searchCriteriaBuilder->create()); - $resultData = $this->addChildData($childProducts->getItems(), $resultData); - - return $resultData; - } - - /** - * Format and add configurable child data to their matching products result items. - * - * @param \Magento\Catalog\Model\Product[] $childProducts - * @param array $resultData - * @return array - */ - private function addChildData(array $childProducts, array $resultData) : array - { - /** @var \Magento\Catalog\Model\Product $childProduct */ - foreach ($childProducts as $childProduct) { - $childData = $this->formatter->format($childProduct); - $childId = (int)$childProduct->getId(); - foreach ($resultData as $key => $item) { - if (isset($item['configurable_product_links']) - && array_key_exists($childId, $item['configurable_product_links']) - ) { - $resultData[$key]['configurable_product_links'][$childId] = $childData; - $categoryLinks = $this->productResource->getCategoryIds($childProduct); - foreach ($categoryLinks as $position => $link) { - $resultData[$key]['configurable_product_links'][$childId]['category_links'][] = - ['position' => $position, 'category_id' => $link]; - } - } - } - } - return $resultData; - } -} diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Variant/Collection.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Variant/Collection.php index cbdb9c97ea0e5..7382a9455f193 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Variant/Collection.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Variant/Collection.php @@ -9,7 +9,6 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Model\Product; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\CollectionFactory; use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection as ChildCollection; use Magento\Catalog\Model\ProductFactory; @@ -47,16 +46,6 @@ class Collection */ private $metadataPool; - /** - * @var FormatterInterface - */ - private $formatter; - - /** - * @var \Magento\Catalog\Model\ResourceModel\Product - */ - private $productResource; - /** * @var int[] */ @@ -67,31 +56,30 @@ class Collection */ private $childrenMap = []; + /** + * @var string[] + */ + private $attributeCodes = []; + /** * @param CollectionFactory $childCollectionFactory * @param ProductFactory $productFactory * @param SearchCriteriaBuilder $searchCriteriaBuilder * @param DataProvider $productDataProvider * @param MetadataPool $metadataPool - * @param FormatterInterface $formatter - * @param \Magento\Catalog\Model\ResourceModel\Product $productResource */ public function __construct( CollectionFactory $childCollectionFactory, ProductFactory $productFactory, SearchCriteriaBuilder $searchCriteriaBuilder, DataProvider $productDataProvider, - MetadataPool $metadataPool, - FormatterInterface $formatter, - \Magento\Catalog\Model\ResourceModel\Product $productResource + MetadataPool $metadataPool ) { $this->childCollectionFactory = $childCollectionFactory; $this->productFactory = $productFactory; $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->productDataProvider = $productDataProvider; $this->metadataPool = $metadataPool; - $this->formatter = $formatter; - $this->productResource = $productResource; } /** @@ -107,6 +95,17 @@ public function addParentId(int $id) : void } } + /** + * Add attributes to collection filter + * + * @param array $attributeCodes + * @return void + */ + public function addEavAttributes(array $attributeCodes) : void + { + $this->attributeCodes = array_replace($this->attributeCodes, $attributeCodes); + } + /** * Retrieve child products from for passed in parent id. * @@ -151,23 +150,15 @@ private function fetch() : array } $this->searchCriteriaBuilder->addFilter($linkField, $childIds, 'in'); - $childProducts = $this->productDataProvider->getList($this->searchCriteriaBuilder->create()); + $childProducts = $this->productDataProvider->getList( + $this->searchCriteriaBuilder->create(), + $this->attributeCodes + ); /** @var Product $childProduct */ foreach ($childProducts->getItems() as $childProduct) { - $formattedChild = $this->formatter->format($childProduct); - $categoryLinks = $this->productResource->getCategoryIds($childProduct); - /** @var Product $item */ - foreach ($childCollection->getItems() as $item) { - if ($childProduct->getId() !== $item->getId()) { - continue; - } - - $parentId = $item->getParentId(); - } - foreach ($categoryLinks as $position => $link) { - $formattedChild['category_links'][] = ['position' => $position, 'category_id' => $link]; - } + $formattedChild = ['model' => $childProduct]; + $parentId = (int)$childProduct->getParentId(); if (!isset($this->childrenMap[$parentId])) { $this->childrenMap[$parentId] = []; } diff --git a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/DownloadableOptions.php b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php similarity index 68% rename from app/code/Magento/DownloadableGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/DownloadableOptions.php rename to app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php index b4e9c4fff3efe..7d236b6f09b39 100644 --- a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/DownloadableOptions.php +++ b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php @@ -5,21 +5,27 @@ */ declare(strict_types = 1); -namespace Magento\DownloadableGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; +namespace Magento\DownloadableGraphQl\Model\Resolver\Product; +use GraphQL\Type\Definition\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Downloadable\Model\Product\Type as Downloadable; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; use Magento\Framework\Data\Collection; +use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Query\EnumLookup; use Magento\Downloadable\Helper\Data as DownloadableHelper; use Magento\Downloadable\Model\ResourceModel\Sample\Collection as SampleCollection; use Magento\Downloadable\Model\ResourceModel\Link\Collection as LinkCollection; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; /** * Format for downloadable product types + * + * {@inheritdoc} */ -class DownloadableOptions implements FormatterInterface +class DownloadableOptions implements ResolverInterface { /** * @var EnumLookup @@ -41,22 +47,30 @@ class DownloadableOptions implements FormatterInterface */ private $linkCollection; + /** + * @var ValueFactory + */ + private $valueFactory; + /** * @param EnumLookup $enumLookup * @param DownloadableHelper $downloadableHelper * @param SampleCollection $sampleCollection * @param LinkCollection $linkCollection + * @param ValueFactory $valueFactory */ public function __construct( EnumLookup $enumLookup, DownloadableHelper $downloadableHelper, SampleCollection $sampleCollection, - LinkCollection $linkCollection + LinkCollection $linkCollection, + ValueFactory $valueFactory ) { $this->enumLookup = $enumLookup; $this->downloadableHelper = $downloadableHelper; $this->sampleCollection = $sampleCollection; $this->linkCollection = $linkCollection; + $this->valueFactory = $valueFactory; } /** @@ -64,23 +78,43 @@ public function __construct( * * {@inheritdoc} */ - public function format(Product $product, array $productData = []) : array - { + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + if (!isset($value['model'])) { + return null; + } + + /** @var Product $product */ + $product = $value['model']; + + $data = null; if ($product->getTypeId() === Downloadable::TYPE_DOWNLOADABLE) { - $samples = $this->sampleCollection->addTitleToResult($product->getStoreId()) - ->addProductToFilter($product->getId()); - $links = $this->linkCollection->addTitleToResult($product->getStoreId()) - ->addPriceToResult($product->getStore()->getWebsiteId()) - ->addProductToFilter($product->getId()); - $productData['downloadable_product_links'] = $this->formatLinks( - $links - ); - $productData['downloadable_product_samples'] = $this->formatSamples( - $samples - ); + if ($field->getName() === 'downloadable_product_links') { + $links = $this->linkCollection->addTitleToResult($product->getStoreId()) + ->addPriceToResult($product->getStore()->getWebsiteId()) + ->addProductToFilter($product->getId()); + $data = $this->formatLinks( + $links + ); + } elseif ($field->getName() === 'downloadable_product_samples') { + $samples = $this->sampleCollection->addTitleToResult($product->getStoreId()) + ->addProductToFilter($product->getId()); + $data = $this->formatSamples( + $samples + ); + } } - return $productData; + $result = function () use ($data) { + return $data; + }; + + return $this->valueFactory->create($result); } /** diff --git a/app/code/Magento/DownloadableGraphQl/etc/graphql.xml b/app/code/Magento/DownloadableGraphQl/etc/graphql.xml index 7e029c4cc174a..35aa6b13961c7 100644 --- a/app/code/Magento/DownloadableGraphQl/etc/graphql.xml +++ b/app/code/Magento/DownloadableGraphQl/etc/graphql.xml @@ -7,8 +7,8 @@ <type xsi:type="OutputType" name="DownloadableProduct"> <implements interface="ProductInterface" copyFields="true"/> <implements interface="CustomizableProductInterface" copyFields="true"/> - <field xsi:type="ObjectArrayOutputField" name="downloadable_product_samples" itemType="DownloadableProductSamples" description="An array containing information about samples of this downloadable product."/> - <field xsi:type="ObjectArrayOutputField" name="downloadable_product_links" itemType="DownloadableProductLinks" description="An array containing information about the links for this downloadable product."/> + <field xsi:type="ObjectArrayOutputField" name="downloadable_product_samples" resolver="Magento\DownloadableGraphQl\Model\Resolver\Product\DownloadableOptions" itemType="DownloadableProductSamples" description="An array containing information about samples of this downloadable product."/> + <field xsi:type="ObjectArrayOutputField" name="downloadable_product_links" resolver="Magento\DownloadableGraphQl\Model\Resolver\Product\DownloadableOptions" itemType="DownloadableProductLinks" description="An array containing information about the links for this downloadable product."/> <field xsi:type="ObjectOutputField" name="links_purchased_separately" type="Int" description="A value of 1 indicates that each link in the array must be purchased separately."/> <field xsi:type="ObjectOutputField" name="links_title" type="String" description="The heading above the list of downloadable products"/> </type> diff --git a/app/code/Magento/DownloadableGraphQl/etc/graphql/di.xml b/app/code/Magento/DownloadableGraphQl/etc/graphql/di.xml index 54b044b565863..8232946045ecb 100644 --- a/app/code/Magento/DownloadableGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/DownloadableGraphQl/etc/graphql/di.xml @@ -6,13 +6,6 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterComposite"> - <arguments> - <argument name="formatterInstances" xsi:type="array"> - <item name="add_downloadable_data" xsi:type="object">Magento\DownloadableGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter\DownloadableOptions</item> - </argument> - </arguments> - </type> <type name="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> <arguments> <argument name="productTypeNameResolvers" xsi:type="array"> diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php new file mode 100644 index 0000000000000..befe9f5ae5791 --- /dev/null +++ b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GroupedProductGraphQl\Model\Resolver; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; + +/** + * {@inheritdoc} + */ +class GroupedItems implements ResolverInterface +{ + /** + * {@inheritDoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + + } +} diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php deleted file mode 100644 index c39f2024d1362..0000000000000 --- a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/DataProvider/Product/Formatter/ProductLinks.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\GroupedProductGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter; - -use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\ProductLink\Link; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterInterface; -use Magento\GroupedProduct\Model\Product\Type\Grouped; - -/** - * Format the product links information to conform to GraphQL schema representation - */ -class ProductLinks implements FormatterInterface -{ - const LINK_TYPE = 'associated'; - - /** - * Format product links data to conform to GraphQL schema - * - * {@inheritdoc} - */ - public function format(Product $product, array $productData = []) : array - { - $productLinks = $product->getProductLinks(); - if ($productLinks && $product->getTypeId() === Grouped::TYPE_CODE) { - /** @var Link $productLink */ - foreach ($productLinks as $productLinkKey => $productLink) { - if ($productLink->getLinkType() === self::LINK_TYPE) { - $data['product'] = $productLink->getData(); - $data['qty'] = $productLink->getExtensionAttributes()->getQty(); - $data['position'] = (int)$productLink->getPosition(); - $productData['items'][$productLinkKey] = $data; - } - } - } else { - $productData['items'] = null; - } - - return $productData; - } -} diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Links/Collection.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Links/Collection.php new file mode 100644 index 0000000000000..5e0bda881bacf --- /dev/null +++ b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Links/Collection.php @@ -0,0 +1,102 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GroupedProductGraphQl\Model\Resolver\Products\Links; + +use Magento\Catalog\Model\Product\Link; +use Magento\Store\Model\StoreManagerInterface; + +/** + * Class Collection + */ +class Collection +{ + /** + * @var Link + */ + private $link; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var int[] + */ + private $parentIds = []; + + /** + * @var array + */ + private $groupedLinkMap = []; + + /** + * Add grouped parent id to collection filter. + * + * @param int $productId + * @return void + */ + public function addParentIdToFilter(int $productId) : void + { + if (!in_array($productId, $this->parentIds)) { + $this->parentIds[] = $productId; + } + } + + /** + * Get array of children association links for a passed in grouped product id + * + * @param int $productId + * @return array|null + */ + public function getGroupedLinksByParentId(int $productId) : ?array + { + $groupedLinks = $this->fetch(); + + if (!isset($groupedLinks[$productId])) { + return null; + } + + return $groupedLinks[$productId]; + } + + /** + * Fetch map of associated grouped products + * + * @return array + */ + private function fetch() : array + { + if (empty($this->parentIds) || !empty($this->groupedLinkMap)) { + return $this->groupedLinkMap; + } + + $collection = $this->link + ->setLinkTypeId(\Magento\GroupedProduct\Model\ResourceModel\Product\Link::LINK_TYPE_GROUPED) + ->getProductCollection(); + $collection + ->setFlag('product_children', true) + ->setIsStrongMode() + ->addProductFilter($this->parentIds) + ->addStoreFilter($this->storeManager->getStore()->getId()) + ->addFilterByRequiredOptions() + ->setPositionOrder(); + + /** @var \Magento\Catalog\Model\Product $item */ + foreach ($collection as $item) { + $this->groupedLinkMap[$item->getParentId()][$item->getId()] + = [ + 'qty' => $item->getQty(), + 'position' => (int)$item->getPosition(), + 'sku' => $item->getSku() + ]; + } + + return $this->groupedLinkMap; + } +} diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php index de948b2be1f2c..9423ddff6eb31 100644 --- a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php +++ b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php @@ -78,7 +78,7 @@ public function process(array $resultData) : array } $this->searchCriteriaBuilder->addFilter(ProductInterface::SKU, $childrenSkus, 'in'); - $childResults = $this->productDataProvider->getList($this->searchCriteriaBuilder->create()); + $childResults = $this->productDataProvider->getList($this->searchCriteriaBuilder->create(), []); $resultData = $this->addChildData($childResults->getItems(), $resultData); return $resultData; @@ -94,7 +94,7 @@ public function process(array $resultData) : array private function addChildData(array $childResults, array $resultData) : array { foreach ($childResults as $child) { - $childData = $this->formatter->format($child); + $childData = ['model' => $child]; $childSku = $child->getSku(); foreach ($resultData as $key => $item) { foreach ($item['items'] as $linkKey => $link) { diff --git a/app/code/Magento/GroupedProductGraphQl/etc/graphql.xml b/app/code/Magento/GroupedProductGraphQl/etc/graphql.xml index aa8dbe8238640..02ca438eb7f3c 100644 --- a/app/code/Magento/GroupedProductGraphQl/etc/graphql.xml +++ b/app/code/Magento/GroupedProductGraphQl/etc/graphql.xml @@ -7,11 +7,11 @@ <type xsi:type="OutputType" name="GroupedProduct"> <implements interface="ProductInterface" copyFields="true"/> <implements interface="PhysicalProductInterface" copyFields="true"/> - <field xsi:type="ObjectArrayOutputField" name="items" itemType="GroupedProductItem" description="An array containing grouped product items"/> + <field xsi:type="ObjectArrayOutputField" name="items" resolver="Magento\GroupedProductGraphQl\Model\Resolver\GroupedItems" itemType="GroupedProductItem" description="An array containing grouped product items"/> </type> <type xsi:type="OutputType" name="GroupedProductItem"> <field xsi:type="ScalarOutputField" name="qty" type="Float" description="The quantity of this grouped product item"/> <field xsi:type="ScalarOutputField" name="position" type="Int" description="The relative position of this item compared to the other group items."/> - <field xsi:type="ObjectOutputField" name="product" type="ProductInterface" description="The ProductInterface object, which contains details about this product option"/> + <field xsi:type="ObjectOutputField" name="product" resolver="Magento\CatalogGraphQl\Model\Resolver\ChildProduct" type="ProductInterface" description="The ProductInterface object, which contains details about this product option"/> </type> </config> diff --git a/app/code/Magento/GroupedProductGraphQl/etc/graphql/di.xml b/app/code/Magento/GroupedProductGraphQl/etc/graphql/di.xml index cdb1d59f2f82d..92debe4de01f6 100644 --- a/app/code/Magento/GroupedProductGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/GroupedProductGraphQl/etc/graphql/di.xml @@ -6,13 +6,6 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\FormatterComposite"> - <arguments> - <argument name="formatterInstances" xsi:type="array"> - <item name="add_grouped_data" xsi:type="object">Magento\GroupedProductGraphQl\Model\Resolver\Products\DataProvider\Product\Formatter\ProductLinks</item> - </argument> - </arguments> - </type> <type name="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite"> <arguments> <argument name="productTypeNameResolvers" xsi:type="array"> From cef710484c7f464b75e3f73d1cd2604c5e7a908e Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 23 Mar 2018 15:58:28 -0500 Subject: [PATCH 195/668] MAGETWO-89292: Implement SDL from prototype - implement copyright --- app/code/Magento/BundleGraphQl/etc/schema.graphql | 3 +++ app/code/Magento/CatalogGraphQl/etc/schema.graphql | 3 +++ app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql | 2 ++ app/code/Magento/CmsUrlRewriteGraphQl/etc/schema.graphql | 3 +++ app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql | 3 +++ app/code/Magento/CustomerGraphQl/etc/schema.graphql | 3 +++ app/code/Magento/DownloadableGraphQl/etc/schema.graphql | 3 +++ app/code/Magento/EavGraphQl/etc/schema.graphql | 3 +++ app/code/Magento/GraphQl/etc/schema.graphql | 3 +++ app/code/Magento/GroupedProductGraphQl/etc/schema.graphql | 3 +++ app/code/Magento/SwatchesGraphQl/etc/schema.graphql | 3 +++ app/code/Magento/TaxGraphQl/etc/schema.graphql | 3 +++ app/code/Magento/UrlRewriteGraphQl/etc/schema.graphql | 3 +++ app/code/Magento/WeeeGraphQl/etc/schema.graphql | 3 +++ 14 files changed, 41 insertions(+) diff --git a/app/code/Magento/BundleGraphQl/etc/schema.graphql b/app/code/Magento/BundleGraphQl/etc/schema.graphql index 27ff71628955f..b6ccb0a376071 100644 --- a/app/code/Magento/BundleGraphQl/etc/schema.graphql +++ b/app/code/Magento/BundleGraphQl/etc/schema.graphql @@ -1,3 +1,6 @@ +#Copyright © Magento, Inc. All rights reserved. +#See COPYING.txt for license details. + type BundleItem { option_id: Int title: String diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphql b/app/code/Magento/CatalogGraphQl/etc/schema.graphql index 1ec984faf2bc4..0175ff6d44f28 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphql +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphql @@ -1,3 +1,6 @@ +#Copyright © Magento, Inc. All rights reserved. +#See COPYING.txt for license details. + type Query { products( search: String, diff --git a/app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql b/app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql index ee1507c3aea36..d3ad98f9855ea 100644 --- a/app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql +++ b/app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql @@ -1,3 +1,5 @@ +#Copyright © Magento, Inc. All rights reserved. +#See COPYING.txt for license details. interface ProductInterface { url_key: String diff --git a/app/code/Magento/CmsUrlRewriteGraphQl/etc/schema.graphql b/app/code/Magento/CmsUrlRewriteGraphQl/etc/schema.graphql index d69641e5a5b6f..6c4374bf5c172 100644 --- a/app/code/Magento/CmsUrlRewriteGraphQl/etc/schema.graphql +++ b/app/code/Magento/CmsUrlRewriteGraphQl/etc/schema.graphql @@ -1,3 +1,6 @@ +#Copyright © Magento, Inc. All rights reserved. +#See COPYING.txt for license details. + enum UrlRewriteEntityTypeEnum { CMS_PAGE } diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql b/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql index 66cc43a1b538e..57fab28ad1fc8 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql +++ b/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql @@ -1,3 +1,6 @@ +#Copyright © Magento, Inc. All rights reserved. +#See COPYING.txt for license details. + type ConfigurableProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface { configurable_product_links: [SimpleProduct] configurable_product_options: [ConfigurableProductOptions] diff --git a/app/code/Magento/CustomerGraphQl/etc/schema.graphql b/app/code/Magento/CustomerGraphQl/etc/schema.graphql index 69c0c9366b62f..1403ef9190f42 100644 --- a/app/code/Magento/CustomerGraphQl/etc/schema.graphql +++ b/app/code/Magento/CustomerGraphQl/etc/schema.graphql @@ -1,3 +1,6 @@ +#Copyright © Magento, Inc. All rights reserved. +#See COPYING.txt for license details. + type Query { customer: Customer @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\Customer") } diff --git a/app/code/Magento/DownloadableGraphQl/etc/schema.graphql b/app/code/Magento/DownloadableGraphQl/etc/schema.graphql index 321b56289b15c..17bb72598a219 100644 --- a/app/code/Magento/DownloadableGraphQl/etc/schema.graphql +++ b/app/code/Magento/DownloadableGraphQl/etc/schema.graphql @@ -1,3 +1,6 @@ +#Copyright © Magento, Inc. All rights reserved. +#See COPYING.txt for license details. + type DownloadableProduct implements ProductInterface, CustomizableProductInterface { downloadable_product_samples: [DownloadableProductSamples] downloadable_product_links: [DownloadableProductLinks] diff --git a/app/code/Magento/EavGraphQl/etc/schema.graphql b/app/code/Magento/EavGraphQl/etc/schema.graphql index 3cd3253778d6b..5072a60aac256 100644 --- a/app/code/Magento/EavGraphQl/etc/schema.graphql +++ b/app/code/Magento/EavGraphQl/etc/schema.graphql @@ -1,3 +1,6 @@ +#Copyright © Magento, Inc. All rights reserved. +#See COPYING.txt for license details. + type Query { customAttributeMetadata(attributes: [AttributeInput!]!): CustomAttributeMetadata @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata") } diff --git a/app/code/Magento/GraphQl/etc/schema.graphql b/app/code/Magento/GraphQl/etc/schema.graphql index 03c264d5cfb65..4890a6249ee8b 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphql +++ b/app/code/Magento/GraphQl/etc/schema.graphql @@ -1,3 +1,6 @@ +#Copyright © Magento, Inc. All rights reserved. +#See COPYING.txt for license details. + type Query { } diff --git a/app/code/Magento/GroupedProductGraphQl/etc/schema.graphql b/app/code/Magento/GroupedProductGraphQl/etc/schema.graphql index fd680e3a95e82..2ded7ab6fe1ef 100644 --- a/app/code/Magento/GroupedProductGraphQl/etc/schema.graphql +++ b/app/code/Magento/GroupedProductGraphQl/etc/schema.graphql @@ -1,3 +1,6 @@ +#Copyright © Magento, Inc. All rights reserved. +#See COPYING.txt for license details. + type GroupedProduct implements ProductInterface, PhysicalProductInterface { items: [GroupedProductItem] } diff --git a/app/code/Magento/SwatchesGraphQl/etc/schema.graphql b/app/code/Magento/SwatchesGraphQl/etc/schema.graphql index f455811125a70..823565dfa15d3 100644 --- a/app/code/Magento/SwatchesGraphQl/etc/schema.graphql +++ b/app/code/Magento/SwatchesGraphQl/etc/schema.graphql @@ -1,3 +1,6 @@ +#Copyright © Magento, Inc. All rights reserved. +#See COPYING.txt for license details. + interface ProductInterface { swatch_image: String } diff --git a/app/code/Magento/TaxGraphQl/etc/schema.graphql b/app/code/Magento/TaxGraphQl/etc/schema.graphql index 1edf98b675dfe..ddd07052a5dee 100644 --- a/app/code/Magento/TaxGraphQl/etc/schema.graphql +++ b/app/code/Magento/TaxGraphQl/etc/schema.graphql @@ -1,3 +1,6 @@ +#Copyright © Magento, Inc. All rights reserved. +#See COPYING.txt for license details. + type BundleProduct { tax_class_id: Int } diff --git a/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphql b/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphql index 5063ffdbef6ff..d6c9cd5843f00 100644 --- a/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphql +++ b/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphql @@ -1,3 +1,6 @@ +#Copyright © Magento, Inc. All rights reserved. +#See COPYING.txt for license details. + type EntityUrl { id: Int canonical_url: String diff --git a/app/code/Magento/WeeeGraphQl/etc/schema.graphql b/app/code/Magento/WeeeGraphQl/etc/schema.graphql index b114bccfd925f..2737101bd9fc2 100644 --- a/app/code/Magento/WeeeGraphQl/etc/schema.graphql +++ b/app/code/Magento/WeeeGraphQl/etc/schema.graphql @@ -1,3 +1,6 @@ +#Copyright © Magento, Inc. All rights reserved. +#See COPYING.txt for license details. + enum PriceAdjustmentCodesEnum { WEE WEETAX From f9a2de61897e5d83896c7848d5be946a7f678187 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Fri, 23 Mar 2018 15:59:42 -0500 Subject: [PATCH 196/668] MAGETWO-88936: Performance - Reduce complexity of ConfigurableVariant --- .../Model/Resolver/ChildProduct.php | 15 +++- .../Model/Resolver/ConfigurableVariant.php | 56 ++++++++----- .../Model/Resolver/Variant/Attributes.php | 78 +++++++++++++++++++ .../Model/Resolver/GroupedItems.php | 12 +++ 4 files changed, 139 insertions(+), 22 deletions(-) create mode 100644 app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/ChildProduct.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/ChildProduct.php index 402e86c8bed75..50926326da2af 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/ChildProduct.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/ChildProduct.php @@ -14,6 +14,7 @@ use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\Framework\GraphQl\Resolver\Value; use Magento\Framework\GraphQl\Resolver\ValueFactory; +use Magento\CatalogGraphQl\Model\Resolver\Products\Attributes\Collection; /** * {@inheritdoc} @@ -30,16 +31,24 @@ class ChildProduct implements ResolverInterface */ private $valueFactory; + /** + * @var Collection + */ + private $collection; + /** * @param ProductDataProvider $productDataProvider * @param ValueFactory $valueFactory + * @param Collection $collection */ public function __construct( ProductDataProvider $productDataProvider, - ValueFactory $valueFactory + ValueFactory $valueFactory, + Collection $collection ) { $this->productDataProvider = $productDataProvider; $this->valueFactory = $valueFactory; + $this->collection = $collection; } /** @@ -51,7 +60,9 @@ public function resolve(Field $field, array $value = null, array $args = null, $ throw new GraphQlInputException(__('No child sku found for product link.')); } $this->productDataProvider->addProductSku($value['sku']); - $this->productDataProvider->addEavAttributes($this->getProductFields($info)); + $fields = $this->getProductFields($info); + $matchedFields = $this->collection->getRequestAttributes($fields); + $this->productDataProvider->addEavAttributes($matchedFields); $result = function () use ($value) { return $this->productDataProvider->getProductBySku($value['sku']); diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/ConfigurableVariant.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/ConfigurableVariant.php index 1441022bfaf6f..1f8333e1a594a 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/ConfigurableVariant.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/ConfigurableVariant.php @@ -15,6 +15,7 @@ use Magento\Framework\GraphQl\Resolver\Value; use Magento\Framework\GraphQl\Resolver\ValueFactory; use Magento\ConfigurableProductGraphQl\Model\Options\Collection as OptionCollection; +use Magento\CatalogGraphQl\Model\Resolver\Products\Attributes\Collection as AttributeCollection; /** * {@inheritdoc} @@ -36,19 +37,27 @@ class ConfigurableVariant implements ResolverInterface */ private $valueFactory; + /** + * @var AttributeCollection + */ + private $attributeCollection; + /** * @param Collection $variantCollection * @param OptionCollection $optionCollection * @param ValueFactory $valueFactory + * @param AttributeCollection $attributeCollection */ public function __construct( Collection $variantCollection, OptionCollection $optionCollection, - ValueFactory $valueFactory + ValueFactory $valueFactory, + AttributeCollection $attributeCollection ) { $this->variantCollection = $variantCollection; $this->optionCollection = $optionCollection; $this->valueFactory = $valueFactory; + $this->attributeCollection = $attributeCollection; } /** @@ -63,6 +72,9 @@ public function resolve(Field $field, array $value = null, array $args = null, $ } $this->variantCollection->addParentId((int)$value['id']); + $fields = $this->getProductFields($info); + $matchedFields = $this->attributeCollection->getRequestAttributes($fields); + $this->variantCollection->addEavAttributes($matchedFields); $this->optionCollection->addProductId((int)$value['id']); $result = function () use ($value) { @@ -70,25 +82,7 @@ public function resolve(Field $field, array $value = null, array $args = null, $ $options = $this->optionCollection->getAttributesByProductId((int)$value['id']) ?: []; $variants = []; foreach ($children as $key => $child) { - $variants[$key] = ['product' => $child]; - foreach ($options as $option) { - $code = $option['attribute_code']; - if (!isset($child[$code])) { - continue; - } - - foreach ($option['values'] as $optionValue) { - if ($optionValue['value_index'] != $child[$code]) { - continue; - } - $variants[$key]['attributes'][] = [ - 'label' => $optionValue['label'], - 'code' => $code, - 'use_default_value' => $optionValue['use_default_value'], - 'value_index' => $optionValue['value_index'] - ]; - } - } + $variants[$key] = ['product' => $child, 'options' => $options]; } return $variants; @@ -96,4 +90,26 @@ public function resolve(Field $field, array $value = null, array $args = null, $ return $this->valueFactory->create($result); } + + /** + * Return field names for all requested product fields. + * + * @param ResolveInfo $info + * @return string[] + */ + private function getProductFields(ResolveInfo $info) + { + $fieldNames = []; + foreach ($info->fieldNodes as $node) { + if ($node->name->value !== 'product') { + continue; + } + + foreach ($node->selectionSet->selections as $selectionNode) { + $fieldNames[] = $selectionNode->name->value; + } + } + + return $fieldNames; + } } diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes.php new file mode 100644 index 0000000000000..9b259d100c592 --- /dev/null +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product; + +use GraphQL\Type\Definition\ResolveInfo; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Option; +use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; + +/** + * Format a product's option information to conform to GraphQL schema representation + */ +class Attributes implements ResolverInterface +{ + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @param ValueFactory $valueFactory + */ + public function __construct(ValueFactory $valueFactory) + { + $this->valueFactory = $valueFactory; + } + + /** + * Format product's option data to conform to GraphQL schema + * + * {@inheritdoc} + */ + public function resolve( + Field $field, + array $value = null, + array $args = null, + $context, + ResolveInfo $info + ): ?Value { + if (!isset($value['options']) || !isset($value['product'])) { + return null; + } + + $result = function () use ($value) { + $data = []; + foreach ($value['options'] as $option) { + $code = $option['attribute_code']; + if (!isset($value['product'][$code])) { + continue; + } + + foreach ($option['values'] as $optionValue) { + if ($optionValue['value_index'] != $value['product'][$code]) { + continue; + } + $data[] = [ + 'label' => $optionValue['label'], + 'code' => $code, + 'use_default_value' => $optionValue['use_default_value'], + 'value_index' => $optionValue['value_index'] + ]; + } + } + + return $data; + }; + + return $this->valueFactory->create($result); + } +} diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php index befe9f5ae5791..8139c4c2aa0f5 100644 --- a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php +++ b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php @@ -11,12 +11,24 @@ use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; +use Magento\GroupedProductGraphQl\Model\Resolver\Products\Links\Collection; /** * {@inheritdoc} */ class GroupedItems implements ResolverInterface { + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @var Collection + */ + private $linksCollection; + /** * {@inheritDoc} */ From 1578562f9345ec51a80b2df989c2cb7bb82c221c Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Fri, 23 Mar 2018 16:01:33 -0500 Subject: [PATCH 197/668] MAGETWO-88936: Add attributes resolver in config --- app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml index 1bb66233caed0..2fb246f3c9503 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml +++ b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml @@ -12,7 +12,7 @@ <field xsi:type="ObjectArrayOutputField" name="configurable_options" itemType="ConfigurableProductOptions" resolver="Magento\ConfigurableProductGraphQl\Model\Resolver\Options"/> </type> <type xsi:type="OutputType" name="ConfigurableVariant"> - <field xsi:type="ObjectArrayOutputField" name="attributes" itemType="ConfigurableAttributeOption"/> + <field xsi:type="ObjectArrayOutputField" name="attributes" itemType="ConfigurableAttributeOption" resolver="Magento\CatalogGraphQl\Model\Resolver\Product\Attributes"/> <field xsi:type="ObjectOutputField" name="product" type="SimpleProduct"/> </type> <type xsi:type="OutputType" name="ConfigurableAttributeOption"> From 87becfebc23a378d2b16df8ae6499d249faccf82 Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Fri, 23 Mar 2018 16:08:35 -0500 Subject: [PATCH 198/668] MAGETWO-88936: Fix namespace --- .../Model/Resolver/Variant/Attributes.php | 2 +- app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes.php index 9b259d100c592..ffe0c06e2ede3 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes.php @@ -5,7 +5,7 @@ */ declare(strict_types = 1); -namespace Magento\CatalogGraphQl\Model\Resolver\Product; +namespace Magento\ConfigurableProductGraphQl\Model\Resolver\Variant; use GraphQL\Type\Definition\ResolveInfo; use Magento\Catalog\Model\Product; diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml index 2fb246f3c9503..de594a0734f96 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml +++ b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml @@ -12,7 +12,7 @@ <field xsi:type="ObjectArrayOutputField" name="configurable_options" itemType="ConfigurableProductOptions" resolver="Magento\ConfigurableProductGraphQl\Model\Resolver\Options"/> </type> <type xsi:type="OutputType" name="ConfigurableVariant"> - <field xsi:type="ObjectArrayOutputField" name="attributes" itemType="ConfigurableAttributeOption" resolver="Magento\CatalogGraphQl\Model\Resolver\Product\Attributes"/> + <field xsi:type="ObjectArrayOutputField" name="attributes" itemType="ConfigurableAttributeOption" resolver="Magento\ConfigurableProductGraphQl\Model\Resolver\Variant\Attributes"/> <field xsi:type="ObjectOutputField" name="product" type="SimpleProduct"/> </type> <type xsi:type="OutputType" name="ConfigurableAttributeOption"> From 8ef4d4a06784d3bd620f3c6d7018d79c62cf38d7 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Fri, 23 Mar 2018 16:10:56 -0500 Subject: [PATCH 199/668] MAGETWO-89260: Fix Travis build issues - fix static test failure --- .../Catalog/Test/Unit/Model/ProductTest.php | 32 ++--- .../Console/Command/GeneratePatchCommand.php | 54 ++++---- .../Console/Command/DeployMarker.php | 30 ++--- .../UpdateProductOptionsObserverTest.php | 24 ++-- .../Theme/Model/Design/Backend/File.php | 6 +- .../Webapi/Test/Unit/Controller/RestTest.php | 126 +++++++++--------- .../Magento/Test/Integrity/ComposerTest.php | 8 +- .../Test/Integrity/Layout/BlockNamesTest.php | 10 +- .../Test/Integrity/Layout/HandlesTest.php | 10 +- .../Api/ExtensibleInterfacesTest.php | 23 ++-- .../Test/Integrity/Readme/ReadmeTest.php | 6 +- .../Magento/Test/Integrity/Xml/SchemaTest.php | 6 +- .../Magento/Test/Legacy/PhtmlTemplateTest.php | 22 +-- .../Unit/Controller/ExtensionGridTest.php | 14 +- 14 files changed, 186 insertions(+), 185 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php index 1ba35dde7ad2f..9c75e8f346909 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php @@ -330,9 +330,9 @@ protected function setUp() $this->mediaGalleryEntryFactoryMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory::class) - ->setMethods(['create']) - ->disableOriginalConstructor() - ->getMock(); + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); $this->metadataServiceMock = $this->createMock(\Magento\Catalog\Api\ProductAttributeRepositoryInterface::class); $this->attributeValueFactory = $this->getMockBuilder(\Magento\Framework\Api\AttributeValueFactory::class) @@ -1171,19 +1171,19 @@ public function testSetMediaGalleryEntries() ]; $entryMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class) - ->setMethods( - [ - 'getId', - 'getFile', - 'getLabel', - 'getPosition', - 'isDisabled', - 'types', - 'getContent', - 'getMediaType' - ] - ) - ->getMockForAbstractClass(); + ->setMethods( + [ + 'getId', + 'getFile', + 'getLabel', + 'getPosition', + 'isDisabled', + 'types', + 'getContent', + 'getMediaType' + ] + ) + ->getMockForAbstractClass(); $result = [ 'value_id' => 1, diff --git a/app/code/Magento/Developer/Console/Command/GeneratePatchCommand.php b/app/code/Magento/Developer/Console/Command/GeneratePatchCommand.php index 7a7deba98ea4e..cc3760b6846d7 100644 --- a/app/code/Magento/Developer/Console/Command/GeneratePatchCommand.php +++ b/app/code/Magento/Developer/Console/Command/GeneratePatchCommand.php @@ -53,33 +53,33 @@ public function __construct(ComponentRegistrar $componentRegistrar) protected function configure() { $this->setName(self::COMMAND_NAME) - ->setDescription('Generate patch and put it in specific folder.') - ->setDefinition([ - new InputArgument( - self::MODULE_NAME, - InputArgument::REQUIRED, - 'Module name' - ), - new InputArgument( - self::INPUT_KEY_PATCH_NAME, - InputArgument::REQUIRED, - 'Patch name' - ), - new InputOption( - self::INPUT_KEY_IS_REVERTABLE, - null, - InputOption::VALUE_OPTIONAL, - 'Check whether patch is revertable or not.', - false - ), - new InputOption( - self::INPUT_KEY_PATCH_TYPE, - null, - InputOption::VALUE_OPTIONAL, - 'Find out what type of patch should be generated.', - 'data' - ), - ]); + ->setDescription('Generate patch and put it in specific folder.') + ->setDefinition([ + new InputArgument( + self::MODULE_NAME, + InputArgument::REQUIRED, + 'Module name' + ), + new InputArgument( + self::INPUT_KEY_PATCH_NAME, + InputArgument::REQUIRED, + 'Patch name' + ), + new InputOption( + self::INPUT_KEY_IS_REVERTABLE, + null, + InputOption::VALUE_OPTIONAL, + 'Check whether patch is revertable or not.', + false + ), + new InputOption( + self::INPUT_KEY_PATCH_TYPE, + null, + InputOption::VALUE_OPTIONAL, + 'Find out what type of patch should be generated.', + 'data' + ), + ]); parent::configure(); } diff --git a/app/code/Magento/NewRelicReporting/Console/Command/DeployMarker.php b/app/code/Magento/NewRelicReporting/Console/Command/DeployMarker.php index e6ef9db3eb6a1..7a8419d57c865 100644 --- a/app/code/Magento/NewRelicReporting/Console/Command/DeployMarker.php +++ b/app/code/Magento/NewRelicReporting/Console/Command/DeployMarker.php @@ -48,21 +48,21 @@ protected function configure() { $this->setName("newrelic:create:deploy-marker"); $this->setDescription("Check the deploy queue for entries and create an appropriate deploy marker.") - ->addArgument( - 'message', - InputArgument::REQUIRED, - 'Deploy Message?' - ) - ->addArgument( - 'change_log', - InputArgument::REQUIRED, - 'Change Log?' - ) - ->addArgument( - 'user', - InputArgument::OPTIONAL, - 'Deployment User' - ); + ->addArgument( + 'message', + InputArgument::REQUIRED, + 'Deploy Message?' + ) + ->addArgument( + 'change_log', + InputArgument::REQUIRED, + 'Change Log?' + ) + ->addArgument( + 'user', + InputArgument::OPTIONAL, + 'Deployment User' + ); parent::configure(); } diff --git a/app/code/Magento/Tax/Test/Unit/Observer/UpdateProductOptionsObserverTest.php b/app/code/Magento/Tax/Test/Unit/Observer/UpdateProductOptionsObserverTest.php index aaaf72b986240..97fb5472a280d 100644 --- a/app/code/Magento/Tax/Test/Unit/Observer/UpdateProductOptionsObserverTest.php +++ b/app/code/Magento/Tax/Test/Unit/Observer/UpdateProductOptionsObserverTest.php @@ -64,18 +64,18 @@ public function testUpdateProductOptions( ->method('getEvent') ->will($this->returnValue($eventObject)); - $objectManager = new ObjectManager($this); - $taxObserverObject = $objectManager->getObject( - \Magento\Tax\Observer\UpdateProductOptionsObserver::class, - [ - 'taxData' => $taxData, - 'registry' => $registry, - ] - ); - - $taxObserverObject->execute($observerObject); - - $this->assertEquals($expected, $frameworkObject->getAdditionalOptions()); + $objectManager = new ObjectManager($this); + $taxObserverObject = $objectManager->getObject( + \Magento\Tax\Observer\UpdateProductOptionsObserver::class, + [ + 'taxData' => $taxData, + 'registry' => $registry, + ] + ); + + $taxObserverObject->execute($observerObject); + + $this->assertEquals($expected, $frameworkObject->getAdditionalOptions()); } /** diff --git a/app/code/Magento/Theme/Model/Design/Backend/File.php b/app/code/Magento/Theme/Model/Design/Backend/File.php index 1e32cb36b4aea..b37628e54aa30 100644 --- a/app/code/Magento/Theme/Model/Design/Backend/File.php +++ b/app/code/Magento/Theme/Model/Design/Backend/File.php @@ -89,9 +89,9 @@ public function beforeSave() $values = $this->getValue(); $value = reset($values) ?: []; if (!isset($value['file'])) { - throw new LocalizedException( - __('%1 does not contain field \'file\'', $this->getData('field_config/field')) - ); + throw new LocalizedException( + __('%1 does not contain field \'file\'', $this->getData('field_config/field')) + ); } if (isset($value['exists'])) { $this->setValue($value['file']); diff --git a/app/code/Magento/Webapi/Test/Unit/Controller/RestTest.php b/app/code/Magento/Webapi/Test/Unit/Controller/RestTest.php index cea006bcbf3df..582d387054ee6 100644 --- a/app/code/Magento/Webapi/Test/Unit/Controller/RestTest.php +++ b/app/code/Magento/Webapi/Test/Unit/Controller/RestTest.php @@ -98,28 +98,28 @@ protected function setUp() $this->_requestMock->expects($this->any())->method('getHttpHost')->willReturn('testHostName.com'); $this->_responseMock = $this->getResponseMock(); $routerMock = $this->getMockBuilder(\Magento\Webapi\Controller\Rest\Router::class)->setMethods(['match']) - ->disableOriginalConstructor()->getMock(); + ->disableOriginalConstructor()->getMock(); $this->_routeMock = $this->getRouteMock(); $this->_serviceMock = $this->getMockBuilder(self::SERVICE_ID)->setMethods([self::SERVICE_METHOD]) - ->disableOriginalConstructor()->getMock(); + ->disableOriginalConstructor()->getMock(); $this->_oauthServiceMock = $this->getMockBuilder(\Magento\Framework\Oauth\OauthInterface::class) - ->setMethods(['validateAccessTokenRequest'])->getMockForAbstractClass(); + ->setMethods(['validateAccessTokenRequest'])->getMockForAbstractClass(); $this->_authorizationMock = $this->getMockBuilder(\Magento\Framework\Webapi\Authorization::class) - ->disableOriginalConstructor()->getMock(); + ->disableOriginalConstructor()->getMock(); $paramsOverriderMock = $this->getMockBuilder(\Magento\Webapi\Controller\Rest\ParamsOverrider::class) - ->setMethods(['overrideParams']) - ->disableOriginalConstructor()->getMock(); + ->setMethods(['overrideParams']) + ->disableOriginalConstructor()->getMock(); $dataObjectProcessorMock = $this->getMockBuilder(\Magento\Framework\Reflection\DataObjectProcessor::class) - ->disableOriginalConstructor() - ->setMethods(['getMethodReturnType']) - ->getMockForAbstractClass(); + ->disableOriginalConstructor() + ->setMethods(['getMethodReturnType']) + ->getMockForAbstractClass(); $layoutMock = $this->getMockBuilder(\Magento\Framework\View\LayoutInterface::class) - ->disableOriginalConstructor()->getMock(); + ->disableOriginalConstructor()->getMock(); $errorProcessorMock = $this->createMock(\Magento\Framework\Webapi\ErrorProcessor::class); $errorProcessorMock->expects($this->any())->method('maskException')->will($this->returnArgument(0)); @@ -127,7 +127,7 @@ protected function setUp() $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->serviceInputProcessorMock = $this->getMockBuilder(\Magento\Framework\Webapi\ServiceInputProcessor::class) - ->disableOriginalConstructor()->setMethods(['process'])->getMock(); + ->disableOriginalConstructor()->setMethods(['process'])->getMock(); $areaListMock = $this->createMock(\Magento\Framework\App\AreaList::class); $areaMock = $this->createMock(\Magento\Framework\App\AreaInterface::class); @@ -160,7 +160,7 @@ protected function setUp() $this->_routeMock->expects($this->any())->method('getServiceClass')->will($this->returnValue(self::SERVICE_ID)); $this->_routeMock->expects($this->any())->method('getServiceMethod') - ->will($this->returnValue(self::SERVICE_METHOD)); + ->will($this->returnValue(self::SERVICE_METHOD)); $routerMock->expects($this->any())->method('match')->will($this->returnValue($this->_routeMock)); @@ -169,8 +169,8 @@ protected function setUp() $this->_serviceMock->expects($this->any())->method(self::SERVICE_METHOD)->will($this->returnValue(null)); $dataObjectProcessorMock->expects($this->any())->method('getMethodReturnType') - ->with(self::SERVICE_ID, self::SERVICE_METHOD) - ->will($this->returnValue('null')); + ->with(self::SERVICE_ID, self::SERVICE_METHOD) + ->will($this->returnValue('null')); $paramsOverriderMock->expects($this->any())->method('overrideParams')->will($this->returnValue([])); @@ -183,12 +183,12 @@ public function testDispatchSchemaRequest() \Magento\Framework\Webapi\Request::REQUEST_PARAM_SERVICES => 'foo', ]; $this->_requestMock->expects($this->any()) - ->method('getPathInfo') - ->willReturn(\Magento\Webapi\Controller\Rest\SchemaRequestProcessor::PROCESSOR_PATH); + ->method('getPathInfo') + ->willReturn(\Magento\Webapi\Controller\Rest\SchemaRequestProcessor::PROCESSOR_PATH); $this->_requestMock->expects($this->any()) - ->method('getParams') - ->will($this->returnValue($params)); + ->method('getParams') + ->will($this->returnValue($params)); $schema = 'Some REST schema content'; $this->swaggerGeneratorMock->expects($this->any())->method('generate')->willReturn($schema); @@ -203,25 +203,25 @@ public function testDispatchAllSchemaRequest() \Magento\Framework\Webapi\Request::REQUEST_PARAM_SERVICES => 'all', ]; $this->_requestMock->expects($this->any()) - ->method('getPathInfo') - ->willReturn(\Magento\Webapi\Controller\Rest\SchemaRequestProcessor::PROCESSOR_PATH); + ->method('getPathInfo') + ->willReturn(\Magento\Webapi\Controller\Rest\SchemaRequestProcessor::PROCESSOR_PATH); $this->_requestMock->expects($this->any()) - ->method('getParam') - ->will( - $this->returnValueMap([ - [ - \Magento\Framework\Webapi\Request::REQUEST_PARAM_SERVICES, - null, - 'all', - ], - ]) - ); + ->method('getParam') + ->will( + $this->returnValueMap([ + [ + \Magento\Framework\Webapi\Request::REQUEST_PARAM_SERVICES, + null, + 'all', + ], + ]) + ); $this->_requestMock->expects($this->any()) - ->method('getParams') - ->will($this->returnValue($params)); + ->method('getParams') + ->will($this->returnValue($params)); $this->_requestMock->expects($this->any()) - ->method('getRequestedServices') - ->will($this->returnValue('all')); + ->method('getRequestedServices') + ->will($this->returnValue('all')); $schema = 'Some REST schema content'; $this->swaggerGeneratorMock->expects($this->any())->method('generate')->willReturn($schema); @@ -238,9 +238,9 @@ private function getRequestProccessotPoolMock() $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->swaggerGeneratorMock = $this->getMockBuilder(\Magento\Webapi\Model\Rest\Swagger\Generator::class) - ->disableOriginalConstructor() - ->setMethods(['generate', 'getListOfServices']) - ->getMockForAbstractClass(); + ->disableOriginalConstructor() + ->setMethods(['generate', 'getListOfServices']) + ->getMockForAbstractClass(); $this->schemaRequestProcessor = $objectManager->getObject( \Magento\Webapi\Controller\Rest\SchemaRequestProcessor::class, @@ -252,9 +252,9 @@ private function getRequestProccessotPoolMock() $this->synchronousRequestProcessor = $this->getMockBuilder(\Magento\Webapi\Controller\Rest\SynchronousRequestProcessor::class) - ->setMethods(['process']) - ->disableOriginalConstructor() - ->getMock(); + ->setMethods(['process']) + ->disableOriginalConstructor() + ->getMock(); return $objectManager->getObject( \Magento\Webapi\Controller\Rest\RequestProcessorPool::class, @@ -273,14 +273,14 @@ private function getRequestProccessotPoolMock() private function getRouteMock() { return $this->getMockBuilder(\Magento\Webapi\Controller\Rest\Router\Route::class) - ->setMethods([ - 'isSecure', - 'getServiceMethod', - 'getServiceClass', - 'getAclResources', - 'getParameters', - ]) - ->disableOriginalConstructor()->getMock(); + ->setMethods([ + 'isSecure', + 'getServiceMethod', + 'getServiceClass', + 'getAclResources', + 'getParameters', + ]) + ->disableOriginalConstructor()->getMock(); } /** @@ -289,18 +289,18 @@ private function getRouteMock() private function getRequestMock() { return $this->getMockBuilder(\Magento\Framework\Webapi\Rest\Request::class) - ->setMethods( - [ - 'isSecure', - 'getRequestData', - 'getParams', - 'getParam', - 'getRequestedServices', - 'getPathInfo', - 'getHttpHost', - 'getMethod', - ] - )->disableOriginalConstructor()->getMock(); + ->setMethods( + [ + 'isSecure', + 'getRequestData', + 'getParams', + 'getParam', + 'getRequestedServices', + 'getPathInfo', + 'getHttpHost', + 'getMethod', + ] + )->disableOriginalConstructor()->getMock(); } /** @@ -309,8 +309,8 @@ private function getRequestMock() private function getResponseMock() { return $this->getMockBuilder(\Magento\Framework\Webapi\Rest\Response::class) - ->setMethods(['sendResponse', 'prepareResponse', 'setHeader']) - ->disableOriginalConstructor() - ->getMock(); + ->setMethods(['sendResponse', 'prepareResponse', 'setHeader']) + ->disableOriginalConstructor() + ->getMock(); } } diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/ComposerTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/ComposerTest.php index 87da2f13e1e24..e9365a9c67034 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/ComposerTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/ComposerTest.php @@ -77,10 +77,10 @@ public function testValidComposerJson() { $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); $invoker( - /** - * @param string $dir - * @param string $packageType - */ + /** + * @param string $dir + * @param string $packageType + */ function ($dir, $packageType) { $file = $dir . '/composer.json'; $this->assertFileExists($file); diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/BlockNamesTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/BlockNamesTest.php index ec1d719df2e5e..3bbada60fc4b9 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/BlockNamesTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/BlockNamesTest.php @@ -14,11 +14,11 @@ public function testBlocksHasName() { $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); $invoker( - /** - * Test validate that blocks without name doesn't exist in layout file - * - * @param string $layoutFile - */ + /** + * Test validate that blocks without name doesn't exist in layout file + * + * @param string $layoutFile + */ function ($layoutFile) { $dom = new \DOMDocument(); $dom->load($layoutFile); diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/HandlesTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/HandlesTest.php index f2370005afba2..3de3d85a222e3 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/HandlesTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/HandlesTest.php @@ -78,11 +78,11 @@ public function testHeadBlockUsage() { $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); $invoker( - /** - * Test validate that head block doesn't exist in layout - * - * @param string $layoutFile - */ + /** + * Test validate that head block doesn't exist in layout + * + * @param string $layoutFile + */ function ($layoutFile) { $dom = new \DOMDocument(); $dom->load($layoutFile); diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Api/ExtensibleInterfacesTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Api/ExtensibleInterfacesTest.php index a0c1f53cd169e..571ed4afbb6ce 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Api/ExtensibleInterfacesTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Api/ExtensibleInterfacesTest.php @@ -24,18 +24,19 @@ public function testGetSetExtensionAttributes() { $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); $invoker( - /** - * @param string $filename - */ + /** + * @param string $filename + */ function ($filename) { $errors = []; $fileContent = file_get_contents($filename); - $extendsFromExtensibleDataInterface = preg_match( - '/' . str_replace('\\', '\\\\', self::EXTENSIBLE_DATA_INTERFACE) . '/', - $fileContent - ); + $pattern = '/' + . str_replace('\\', '\\\\', self::EXTENSIBLE_DATA_INTERFACE) + . '/'; + $extendsFromExtensibleDataInterface = preg_match($pattern, $fileContent); + $namespacePattern = '/namespace ([\w\\\\]+).*interface ([\w\\\\]+)/s'; if ($extendsFromExtensibleDataInterface - && preg_match('/namespace ([\w\\\\]+).*interface ([\w\\\\]+)/s', $fileContent, $matches) + && preg_match($namespacePattern, $fileContent, $matches) ) { $namespace = $matches[1]; $interfaceName = $matches[2]; @@ -158,9 +159,9 @@ public function testExtensibleClassesWithMissingInterface() { $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); $invoker( - /** - * @param string $filename - */ + /** + * @param string $filename + */ function ($filename) { $errors = []; $fileContent = file_get_contents($filename); diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Readme/ReadmeTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Readme/ReadmeTest.php index 3ba5b26615af6..8e33698ec15d7 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/Readme/ReadmeTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Readme/ReadmeTest.php @@ -35,9 +35,9 @@ public function testReadmeFiles() { $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); $invoker( - /** - * @param string $dir - */ + /** + * @param string $dir + */ function ($dir) { $file = $dir . DIRECTORY_SEPARATOR . self::README_FILENAME; $this->assertFileExists( diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Xml/SchemaTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Xml/SchemaTest.php index 30e0dc621f355..5aedd806692d8 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/Xml/SchemaTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Xml/SchemaTest.php @@ -14,9 +14,9 @@ public function testXmlFiles() { $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); $invoker( - /** - * @param string $filename - */ + /** + * @param string $filename + */ function ($filename) { $dom = new \DOMDocument(); $xmlFile = file_get_contents($filename); diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/PhtmlTemplateTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/PhtmlTemplateTest.php index 34d3e7b77d291..7cb65c27d7fe6 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/PhtmlTemplateTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/PhtmlTemplateTest.php @@ -13,11 +13,11 @@ public function testBlockVariableInsteadOfThis() { $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); $invoker( - /** - * Test usage of methods and variables in template through $this - * - * @param string $file - */ + /** + * Test usage of methods and variables in template through $this + * + * @param string $file + */ function ($file) { $this->assertNotRegExp( '/this->(?!helper)\S*/iS', @@ -61,12 +61,12 @@ public function testObsoleteJavascriptAttributeType() { $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); $invoker( - /** - * "text/javascript" type attribute in not obligatory to use in templates due to HTML5 standards. - * For more details please go to "http://www.w3.org/TR/html5/scripting-1.html". - * - * @param string $file - */ + /** + * "text/javascript" type attribute in not obligatory to use in templates due to HTML5 standards. + * For more details please go to "http://www.w3.org/TR/html5/scripting-1.html". + * + * @param string $file + */ function ($file) { $this->assertNotRegexp( '/type="text\/javascript"/', diff --git a/setup/src/Magento/Setup/Test/Unit/Controller/ExtensionGridTest.php b/setup/src/Magento/Setup/Test/Unit/Controller/ExtensionGridTest.php index e69bf229c4e69..febcbd1f8dbd4 100644 --- a/setup/src/Magento/Setup/Test/Unit/Controller/ExtensionGridTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Controller/ExtensionGridTest.php @@ -110,13 +110,13 @@ public function testExtensionsAction() ->method('syncPackagesData') ->willReturn($this->lastSyncData); $this->packagesAuthMock->expects($this->once()) - ->method('getAuthJsonData') - ->willReturn( - [ - 'username' => 'someusername', - 'password' => 'somepassword' - ] - ); + ->method('getAuthJsonData') + ->willReturn( + [ + 'username' => 'someusername', + 'password' => 'somepassword' + ] + ); $jsonModel = $this->controller->extensionsAction(); $this->assertInstanceOf(\Zend\View\Model\JsonModel::class, $jsonModel); From 9e65459a15db93b71c4fa5cc19620e2286a034ef Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 23 Mar 2018 16:16:57 -0500 Subject: [PATCH 200/668] MAGETWO-89292: Implement SDL from prototype - remove un-necesary files --- app/code/Magento/GraphQl/etc/di.xml | 37 ----- .../Config/Common/Converter/XmlConverter.php | 61 -------- .../Framework/GraphQl/Config/Converter.php | 48 ------- .../Config/Converter/Normalizer/Enum.php | 38 ----- .../Config/Converter/Normalizer/Input.php | 51 ------- .../Config/Converter/Normalizer/Output.php | 53 ------- .../Config/Converter/NormalizerComposite.php | 40 ------ .../Config/Converter/NormalizerInterface.php | 22 --- .../Converter/Type/Formatter/Description.php | 33 ----- .../Converter/Type/Formatter/Fields.php | 131 ------------------ .../Converter/Type/Formatter/Interfaces.php | 54 -------- .../Converter/Type/FormatterComposite.php | 40 ------ .../Converter/Type/FormatterInterface.php | 24 ---- .../GraphQl/Config/GraphQlReader.php | 9 -- 14 files changed, 641 deletions(-) delete mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Common/Converter/XmlConverter.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Converter.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Enum.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Input.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Output.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerComposite.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerInterface.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Description.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Fields.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Interfaces.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterComposite.php delete mode 100644 lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterInterface.php diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index c34efb900bbf9..2e793fab34707 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -46,25 +46,10 @@ <virtualType name="Magento\Framework\GraphQl\Config\Reader" type="Magento\Framework\GraphQl\Config\Common\Reader"> <arguments> <argument name="readers" xsi:type="array"> - <!--TODO: Delete all xml configs--> - <!--<item name="xmlReader" xsi:type="object">Magento\Framework\GraphQl\Config\XmlReader</item>--> <item name="graphQlReader" xsi:type="object">Magento\Framework\GraphQl\Config\GraphQlReader</item> </argument> </arguments> </virtualType> - <virtualType name="Magento\Framework\GraphQl\Config\XmlReader" type="Magento\Framework\Config\Reader\Filesystem"> - <arguments> - <argument name="converter" xsi:type="object">Magento\Framework\GraphQl\Config\Converter</argument> - <argument name="schemaLocator" xsi:type="object">Magento\Framework\GraphQl\Config\SchemaLocator</argument> - <argument name="fileName" xsi:type="string">graphql.xml</argument> - <argument name="idAttributes" xsi:type="array"> - <item name="/config/type" xsi:type="string">name</item> - <item name="/config/type/field" xsi:type="string">name</item> - <item name="/config/type/item" xsi:type="string">name</item> - <item name="/config/type/implements" xsi:type="string">interface</item> - </argument> - </arguments> - </virtualType> <type name="Magento\Framework\GraphQl\Type\Output\OutputFactory"> <arguments> <argument name="prototypes" xsi:type="array"> @@ -97,28 +82,6 @@ </argument> </arguments> </type> - <type name="Magento\Framework\GraphQl\Config\Converter"> - <arguments> - <argument name="normalizer" xsi:type="object">Magento\Framework\GraphQl\Config\Converter\NormalizerComposite</argument> - </arguments> - </type> - <type name="Magento\Framework\GraphQl\Config\Converter\NormalizerComposite"> - <arguments> - <argument name="normalizers" xsi:type="array"> - <item name="output" xsi:type="object">Magento\Framework\GraphQl\Config\Converter\Normalizer\Output</item> - </argument> - </arguments> - </type> - <preference for="Magento\Framework\GraphQl\Config\Converter\Type\FormatterInterface" type="Magento\Framework\GraphQl\Config\Converter\Type\FormatterComposite"/> - <type name="Magento\Framework\GraphQl\Config\Converter\Type\FormatterComposite"> - <arguments> - <argument name="formatters" xsi:type="array"> - <item name="description" xsi:type="object">Magento\Framework\GraphQl\Config\Converter\Type\Formatter\Description</item> - <item name="fields" xsi:type="object">Magento\Framework\GraphQl\Config\Converter\Type\Formatter\Fields</item> - <item name="interfaces" xsi:type="object">Magento\Framework\GraphQl\Config\Converter\Type\Formatter\Interfaces</item> - </argument> - </arguments> - </type> <type name="Magento\Framework\GraphQl\Config\GraphQlReader\TypeReader"> <arguments> <argument name="typeReaders" xsi:type="array"> diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Common/Converter/XmlConverter.php b/lib/internal/Magento/Framework/GraphQl/Config/Common/Converter/XmlConverter.php deleted file mode 100644 index 64b244d69391e..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Config/Common/Converter/XmlConverter.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Framework\GraphQl\Config\Common\Converter; - -use Magento\Framework\Config\ConverterInterface; - -/** - * GraphQL configuration converter. - * - * Converts configuration data stored in XML format into corresponding PHP array. - */ -class XmlConverter implements ConverterInterface -{ - /** - * Converts GraphQL XML node describing schema into processable array. - * - * @param \DOMNode $source - * @return array|string - */ - private function convertNodeToArray(\DOMNode $source) - { - $converted = []; - if ($source->hasAttributes()) { - $attributes = $source->attributes; - foreach ($attributes as $attribute) { - $converted[$attribute->name] = $attribute->value; - } - } - if ($source->hasChildNodes()) { - $childNodes = $source->childNodes; - if ($childNodes->length == 1) { - $child = $childNodes->item(0); - if ($child->nodeType == XML_TEXT_NODE) { - $converted['_value'] = $child->nodeValue; - return count($converted) == 1 ? $converted['_value'] : $converted; - } - } - foreach ($childNodes as $child) { - if (! $child instanceof \DOMCharacterData) { - $converted[$child->nodeName][] = $this->convertNodeToArray($child); - } - } - } - return $converted; - } - - /** - * Converts GraphQL XML document describing schema into processable array. - * - * @param \DOMDocument $source - * @return array - */ - public function convert($source) : array - { - return $this->convertNodeToArray($source); - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter.php deleted file mode 100644 index ad28e7e4f46cb..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Framework\GraphQl\Config; - -use Magento\Framework\Config\ConverterInterface; -use Magento\Framework\GraphQl\Config\Common\Converter\XmlConverter; -use Magento\Framework\GraphQl\Config\Converter\NormalizerInterface; - -/** - * Convert data read from configuration sources into a format readable by GraphQL schema implementations - */ -class Converter implements ConverterInterface -{ - /** - * @var XmlConverter - */ - private $xmlConverter; - - /** - * @var NormalizerInterface - */ - private $normalizer; - - /** - * @param XmlConverter $xmlConverter - * @param NormalizerInterface $normalizer - */ - public function __construct(XmlConverter $xmlConverter, NormalizerInterface $normalizer) - { - $this->xmlConverter = $xmlConverter; - $this->normalizer = $normalizer; - } - - /** - * Converts XML document into a formatted array mirroring the XML structure. - * - * @param \DOMDocument $source - * @return array - */ - public function convert($source) : array - { - return $this->normalizer->normalize($this->xmlConverter->convert($source)); - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Enum.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Enum.php deleted file mode 100644 index 90f20d00c970d..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Enum.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Config\Converter\Normalizer; - -use Magento\Framework\GraphQl\Config\Converter\NormalizerInterface; - -/** - * Normalize enum types to fit requisite structure for building a GraphQL schema. - */ -class Enum implements NormalizerInterface -{ - /** - * {@inheritDoc} - */ - public function normalize(array $source): array - { - $enums = []; - foreach ($source['config'][0]['type'] as $entry) { - if ($entry['type'] !== 'Enum') { - continue; - } - if (isset($entry['description'])) { - $enums[$entry['name']]['description'] = implode(PHP_EOL, $entry['description']); - } - $enums[$entry['name']]['name'] = $entry['name']; - $enums[$entry['name']]['type'] = 'graphql_enum'; - foreach ($entry['item'] as $item) { - $enums[$entry['name']]['items'][$item['_value']] = $item; - } - } - return $enums; - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Input.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Input.php deleted file mode 100644 index c2d690c40bcb0..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Input.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Config\Converter\Normalizer; - -use Magento\Framework\GraphQl\Config\Converter\NormalizerInterface; -use Magento\Framework\GraphQl\Config\Converter\Type\FormatterInterface; - -/** - * Normalize input object types for consumption by Schema processors. - */ -class Input implements NormalizerInterface -{ - /** - * @var FormatterInterface - */ - private $formatter; - - /** - * @param FormatterInterface $formatter - */ - public function __construct(FormatterInterface $formatter) - { - $this->formatter = $formatter; - } - - /** - * {@inheritDoc} - */ - public function normalize(array $source): array - { - $configKey = 'graphql_input'; - $configType = 'InputType'; - $requiredAttributes = ['name']; - - $entries = []; - foreach ($source['config'][0]['type'] as $entry) { - if ($entry['type'] !== $configType) { - continue; - } - $entries[$entry['name']] = array_intersect_key($entry, array_flip($requiredAttributes)); - $entries[$entry['name']]['type'] = $configKey; - $entries[$entry['name']] = array_merge($entries[$entry['name']], $this->formatter->format($entry)); - } - return $entries; - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Output.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Output.php deleted file mode 100644 index 417758cf2bdc6..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Normalizer/Output.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Config\Converter\Normalizer; - -use Magento\Framework\GraphQl\Config\Converter\Type\FormatterInterface; -use Magento\Framework\GraphQl\Config\Converter\NormalizerInterface; - -/** - * Normalize output and interface types from a configured GraphQL Schema. - */ -class Output implements NormalizerInterface -{ - /** - * @var FormatterInterface - */ - private $formatter; - - /** - * @param FormatterInterface $formatter - */ - public function __construct(FormatterInterface $formatter) - { - $this->formatter = $formatter; - } - - /** - * {@inheritDoc} - */ - public function normalize(array $source): array - { - foreach ($source as $interface) { - if ($interface['type'] == 'graphql_interface') { - foreach ($source as $typeName => $type) { - if (isset($type['implements']) - && isset($type['implements'][$interface['name']]) - && isset($type['implements'][$interface['name']]['copyFields']) - && $type['implements'][$interface['name']]['copyFields'] === true - ) { - $source[$typeName]['fields'] = isset($type['fields']) - ? array_replace($interface['fields'], $type['fields']) : $interface['fields']; - } - } - } - } - - return $source; - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerComposite.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerComposite.php deleted file mode 100644 index fa45f595a7bc1..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerComposite.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Config\Converter; - -/** - * {@inheritdoc} - */ -class NormalizerComposite implements NormalizerInterface -{ - /** - * @var NormalizerInterface[] - */ - private $normalizers; - - /** - * @param NormalizerInterface[] $normalizers - */ - public function __construct(array $normalizers) - { - $this->normalizers = $normalizers; - } - - /** - * {@inheritDoc} - */ - public function normalize(array $source) : array - { - $normalizedResult = []; - foreach ($this->normalizers as $normalizer) { - $normalizedResult = array_merge($normalizedResult, $normalizer->normalize($source)); - } - - return $normalizedResult; - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerInterface.php deleted file mode 100644 index 203be0c6dd2b4..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/NormalizerInterface.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Config\Converter; - -/** - * Normalize XML structured GraphQL data that was converted to an array. - */ -interface NormalizerInterface -{ - /** - * Normalize XML formatted array to a format readable by GraphQL element processing. - * - * @param $source - * @return array - */ - public function normalize(array $source) : array; -} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Description.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Description.php deleted file mode 100644 index 86d845bd0f493..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Description.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Config\Converter\Type\Formatter; - -use Magento\Framework\GraphQl\Config\Converter\Type\FormatterInterface; - -/** - * Format description of type if present. - */ -class Description implements FormatterInterface -{ - /** - * {@inheritDoc} - * Input format: - * ['description' => $descriptionString] - * - * Output format: - * ['description' => $descriptionString] or [] - */ - public function format(array $entry): array - { - if (isset($entry['description'])) { - return ['description' => $entry['description']]; - } else { - return []; - } - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Fields.php deleted file mode 100644 index 5899383042705..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Fields.php +++ /dev/null @@ -1,131 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Config\Converter\Type\Formatter; - -use Magento\Framework\GraphQl\Config\Converter\Type\FormatterInterface; - -/** - * Format type's fields and their corresponding data parts. - */ -class Fields implements FormatterInterface -{ - /** - * {@inheritDoc} - * - * Format of input entry should conform to the following structure for fields to be processed correctly: - * ['field' => [ // Required - * $indexOfField => [ // At least 1 item required - * 'name' => $nameOfField, // Required - * 'type' => $nameOfFieldType, // Required - * 'required => $boolean, // Optional - will default to false if not specified - * 'itemType' => $nameOfListItemType, // Required if field is a list - * 'resolver' => $fullyQualifiedResolverClassName, // Required only if field needs custom resolution - * 'description' => $descriptionString, // Optional - * 'argument' => [ // Optional - * 'name' => $argumentName, // Required if arguments exist - * 'type' => $argumentTypeName, // Required if arguments exist - * [...] // Other optional type data from argument - * ], - * ], - * . - * . - * . - * ] - * - * Format of output entry will have the following structure: - * ['fields => [ - * $fieldName => [ - * 'name' => $fieldName, - * 'type' => $typeName, - * 'required => $isRequiredField, // Defaults to false - * 'itemType => $nameOfListItemType, // Present only if list type, - * 'resolver' => $fullyQualifiedResolverClassName, // Present only if custom type resolution required - * 'description' => $descriptionString, // Present only if configured - * 'arguments' => [ // Present only if field has configured arguments - * $argumentName => [ - * 'name' => $argumentName, - * 'type' => $argumentTypeName, - * [...] // Other optional type data from argument - * ], - * ] - * ], - * . - * . - * . - * ] - */ - public function format(array $entry): array - { - $fields = []; - if (!empty($entry['field'])) { - foreach ($entry['field'] as $field) { - $fields['fields'][$field['name']] = [ - 'name' => $field['name'], - 'type' => isset($field['itemType']) ? $field['itemType'] : $field['type'] - ]; - $fields['fields'][$field['name']] = array_merge( - $fields['fields'][$field['name']], - $this->formatBoolean($field, 'required') - ); - $fields['fields'][$field['name']] = array_merge( - $fields['fields'][$field['name']], - $this->formatString($field, 'itemType') - ); - $fields['fields'][$field['name']] = array_merge( - $fields['fields'][$field['name']], - $this->formatString($field, 'resolver') - ); - $fields['fields'][$field['name']] = array_merge( - $fields['fields'][$field['name']], - $this->formatString($field, 'description') - ); - $arguments = []; - if (isset($field['argument'])) { - foreach ($field['argument'] as $argument) { - $arguments[$argument['name']] = $argument; - } - } - $fields['fields'][$field['name']]['arguments'] = $arguments; - } - } - - return $fields; - } - - /** - * Format string if set, otherwise return empty array. - * - * @param array $field - * @param string $name - * @return array - */ - private function formatString(array $field, string $name) : array - { - if (isset($field[$name])) { - return [$name => $field[$name]]; - } else { - return []; - } - } - - /** - * Format boolean to true if set and set to 'true', otherwise set to false. - * - * @param array $field - * @param string $name - * @return array - */ - private function formatBoolean(array $field, string $name) - { - if (isset($field[$name]) && $field[$name] == 'true') { - return [$name => true]; - } else { - return [$name => false]; - } - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Interfaces.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Interfaces.php deleted file mode 100644 index d465dbffbc3fd..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/Formatter/Interfaces.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Config\Converter\Type\Formatter; - -use Magento\Framework\GraphQl\Config\Converter\Type\FormatterInterface; - -/** - * Add interfaces to a type if declared. - */ -class Interfaces implements FormatterInterface -{ - /** - * {@inheritDoc} - * Format of input entry should conform to the following structure for interfaces that output type implements to be - * processed correctly: - * ['implements' => [ // Required - * $indexOfImplementedInterface => [ - * 'interface' => $nameOfInterfaceType, // Required - * 'copyFields' => $shouldCopyFields // Optional - should be string that says "true" or "false" - * ], - * . - * . - * . - * ] - * - * Format of output entry for interfaces that type implements is as follows: - * ['implements' => [ - * $interfaceName => [ - * 'interface' => $interfaceName, - * 'copyFields' => $shouldCopyFields // Present only if given in input, string that says "true" or "false" - * ], - * . - * . - * . - * ] - */ - public function format(array $entry): array - { - if (!empty($entry['implements'])) { - $implements = []; - foreach ($entry['implements'] as $interface) { - $implements['implements'][$interface['interface']] = $interface; - } - return $implements; - } else { - return []; - } - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterComposite.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterComposite.php deleted file mode 100644 index 0aa359c047e29..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterComposite.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Config\Converter\Type; - -/** - * {@inheritdoc} - */ -class FormatterComposite implements FormatterInterface -{ - /** - * @var FormatterInterface[] - */ - private $formatters; - - /** - * @param FormatterInterface[] $formatters - */ - public function __construct(array $formatters) - { - $this->formatters = $formatters; - } - - /** - * {@inheritdoc} - */ - public function format(array $entry) : array - { - $formattedEntry = []; - foreach ($this->formatters as $formatter) { - $formattedEntry = array_merge_recursive($formattedEntry, $formatter->format($entry)); - } - - return $formattedEntry; - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterInterface.php b/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterInterface.php deleted file mode 100644 index 14783e73faf0b..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Config/Converter/Type/FormatterInterface.php +++ /dev/null @@ -1,24 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\Framework\GraphQl\Config\Converter\Type; - -use Magento\Framework\GraphQl\Type\Schema; - -/** - * Format GraphQL Type and Interface array structures to allow for configuration mapping for a @see Schema. - */ -interface FormatterInterface -{ - /** - * Format configured interface or type array to mapping-readable format - * - * @param array $entry - * @return array - */ - public function format(array $entry) : array; -} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php index 7cde4306304f5..1f20383169cc0 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php @@ -10,7 +10,6 @@ use Magento\Framework\Config\FileResolverInterface; use Magento\Framework\GraphQl\Config\GraphQlReader\TypeReader; use Magento\Framework\Config\ReaderInterface; -use Magento\Framework\GraphQl\Config\Converter\NormalizerComposite; class GraphQlReader implements ReaderInterface { @@ -39,28 +38,20 @@ class GraphQlReader implements ReaderInterface */ private $defaultScope; - /** - * @var NormalizerComposite - */ - private $normalizer; - /** * @param FileResolverInterface $fileResolver * @param TypeReader $typeReader - * @param NormalizerComposite $normalizer * @param string $fileName * @param string $defaultScope */ public function __construct( FileResolverInterface $fileResolver, TypeReader $typeReader, - NormalizerComposite $normalizer, $fileName = 'schema.graphql', $defaultScope = 'global' ) { $this->fileResolver = $fileResolver; $this->typeReader = $typeReader; - $this->normalizer = $normalizer; $this->defaultScope = $defaultScope; $this->fileName = $fileName; } From 26374bd947d13967bad9af8e1fde73904bfd91bd Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 23 Mar 2018 16:31:18 -0500 Subject: [PATCH 201/668] MAGETWO-89292: Implement SDL from prototype - remove un-necesary fields implementations --- .../Magento/CatalogGraphQl/etc/schema.graphql | 1 - .../etc/schema.graphql | 31 ------------------- .../SwatchesGraphQl/etc/schema.graphql | 24 -------------- .../Magento/TaxGraphQl/etc/schema.graphql | 26 ++-------------- 4 files changed, 3 insertions(+), 79 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphql b/app/code/Magento/CatalogGraphQl/etc/schema.graphql index 0175ff6d44f28..fa1fb3d28955c 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphql +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphql @@ -197,7 +197,6 @@ type PriceAdjustment { } enum PriceAdjustmentCodesEnum { - TAX } enum PriceAdjustmentDescriptionEnum { diff --git a/app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql b/app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql index d3ad98f9855ea..b4d1a5b79ae29 100644 --- a/app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql +++ b/app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql @@ -6,37 +6,6 @@ interface ProductInterface { url_path: String } -type VirtualProduct { - url_key: String - url_path: String -} - -type SimpleProduct { - url_key: String - url_path: String -} - - -type BundleProduct { - url_key: String - url_path: String -} - -type ConfigurableProduct { - url_key: String - url_path: String -} - -type DownloadableProduct { - url_key: String - url_path: String -} - -type GroupedProduct { - url_key: String - url_path: String -} - input ProductFilterInput { url_key: FilterTypeInput url_path: FilterTypeInput diff --git a/app/code/Magento/SwatchesGraphQl/etc/schema.graphql b/app/code/Magento/SwatchesGraphQl/etc/schema.graphql index 823565dfa15d3..f775426d5157e 100644 --- a/app/code/Magento/SwatchesGraphQl/etc/schema.graphql +++ b/app/code/Magento/SwatchesGraphQl/etc/schema.graphql @@ -5,30 +5,6 @@ interface ProductInterface { swatch_image: String } -type VirtualProduct { - swatch_image: String -} - -type SimpleProduct { - swatch_image: String -} - -type BundleProduct { - swatch_image: String -} - -type ConfigurableProduct { - swatch_image: String -} - -type DownloadableProduct { - swatch_image: String -} - -type GroupedProduct { - swatch_image: String -} - input ProductFilterInput { swatch_image: FilterTypeInput } diff --git a/app/code/Magento/TaxGraphQl/etc/schema.graphql b/app/code/Magento/TaxGraphQl/etc/schema.graphql index ddd07052a5dee..f9e5cc1076b9c 100644 --- a/app/code/Magento/TaxGraphQl/etc/schema.graphql +++ b/app/code/Magento/TaxGraphQl/etc/schema.graphql @@ -1,22 +1,6 @@ #Copyright © Magento, Inc. All rights reserved. #See COPYING.txt for license details. -type BundleProduct { - tax_class_id: Int -} - -type ConfigurableProduct { - tax_class_id: Int -} - -type DownloadableProduct { - tax_class_id: Int -} - -type GroupedProduct { - tax_class_id: Int -} - input ProductFilterInput { tax_class_id: FilterTypeInput } @@ -29,10 +13,6 @@ input ProductSortInput { tax_class_id: SortEnum } -type SimpleProduct { - tax_class_id: Int -} - -type VirtualProduct { - tax_class_id: Int -} +enum PriceAdjustmentCodesEnum { + TAX +} \ No newline at end of file From 48bcd4b4c1c5941a54f3b763177c50a603acda49 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 23 Mar 2018 16:40:00 -0500 Subject: [PATCH 202/668] MAGETWO-89292: Implement SDL from prototype - remove un-necesary fields implementations --- app/code/Magento/TaxGraphQl/etc/schema.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/TaxGraphQl/etc/schema.graphql b/app/code/Magento/TaxGraphQl/etc/schema.graphql index f9e5cc1076b9c..4fc0f5d9fb32c 100644 --- a/app/code/Magento/TaxGraphQl/etc/schema.graphql +++ b/app/code/Magento/TaxGraphQl/etc/schema.graphql @@ -15,4 +15,4 @@ input ProductSortInput { enum PriceAdjustmentCodesEnum { TAX -} \ No newline at end of file +} From 479a6cbf0dde70d4b6410793c49e16de7f72764e Mon Sep 17 00:00:00 2001 From: Eric Bohanon <ebohanon@magento.com> Date: Fri, 23 Mar 2018 17:10:16 -0500 Subject: [PATCH 203/668] MAGETWO-88936: Fix tests --- .../Magento/BundleGraphQl/etc/graphql.xml | 2 +- .../Model/Resolver/ChildProduct.php | 89 ------------------- .../CatalogGraphQl/Model/Resolver/Product.php | 81 +++++++++++++---- .../Products/DataProvider/Product.php | 10 ++- .../Model/Resolver/Products/Query/Filter.php | 10 ++- .../GroupedProductGraphQl/etc/graphql.xml | 2 +- 6 files changed, 78 insertions(+), 116 deletions(-) delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/ChildProduct.php diff --git a/app/code/Magento/BundleGraphQl/etc/graphql.xml b/app/code/Magento/BundleGraphQl/etc/graphql.xml index 1d90da0c35730..c1b23565f825f 100644 --- a/app/code/Magento/BundleGraphQl/etc/graphql.xml +++ b/app/code/Magento/BundleGraphQl/etc/graphql.xml @@ -36,7 +36,7 @@ <field xsi:type="ScalarOutputField" name="price" type="Float" description="The price of the selected option"/> <field xsi:type="ObjectOutputField" name="price_type" type="PriceTypeEnum" description="One of FIXED, PERCENT, or DYNAMIC"/> <field xsi:type="ScalarOutputField" name="can_change_quantity" type="Boolean" description="Indicates whether the customer can change the number of items for this option"/> - <field xsi:type="ObjectOutputField" name="product" type="ProductInterface" resolver="Magento\CatalogGraphQl\Model\Resolver\ChildProduct" description="The ProductInterface object, which contains details about this product option"/> + <field xsi:type="ObjectOutputField" name="product" type="ProductInterface" resolver="Magento\CatalogGraphQl\Model\Resolver\Product" description="The ProductInterface object, which contains details about this product option"/> </type> <type xsi:type="Enum" name="ShipBundleItemsEnum"> <item name="together">TOGETHER</item> diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/ChildProduct.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/ChildProduct.php deleted file mode 100644 index 50926326da2af..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/ChildProduct.php +++ /dev/null @@ -1,89 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types = 1); - -namespace Magento\CatalogGraphQl\Model\Resolver; - -use GraphQL\Type\Definition\ResolveInfo; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred\Product as ProductDataProvider; -use Magento\Framework\GraphQl\Config\Data\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Resolver\ResolverInterface; -use Magento\Framework\GraphQl\Resolver\Value; -use Magento\Framework\GraphQl\Resolver\ValueFactory; -use Magento\CatalogGraphQl\Model\Resolver\Products\Attributes\Collection; - -/** - * {@inheritdoc} - */ -class ChildProduct implements ResolverInterface -{ - /** - * @var ProductDataProvider - */ - private $productDataProvider; - - /** - * @var ValueFactory - */ - private $valueFactory; - - /** - * @var Collection - */ - private $collection; - - /** - * @param ProductDataProvider $productDataProvider - * @param ValueFactory $valueFactory - * @param Collection $collection - */ - public function __construct( - ProductDataProvider $productDataProvider, - ValueFactory $valueFactory, - Collection $collection - ) { - $this->productDataProvider = $productDataProvider; - $this->valueFactory = $valueFactory; - $this->collection = $collection; - } - - /** - * {@inheritDoc} - */ - public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?Value - { - if (!isset($value['sku'])) { - throw new GraphQlInputException(__('No child sku found for product link.')); - } - $this->productDataProvider->addProductSku($value['sku']); - $fields = $this->getProductFields($info); - $matchedFields = $this->collection->getRequestAttributes($fields); - $this->productDataProvider->addEavAttributes($matchedFields); - - $result = function () use ($value) { - return $this->productDataProvider->getProductBySku($value['sku']); - }; - - return $this->valueFactory->create($result); - } - - /** - * Return field names for all requested product fields. - * - * @param ResolveInfo $info - * @return string[] - */ - private function getProductFields(ResolveInfo $info) - { - $fieldNames = []; - foreach ($info->fieldNodes as $node) { - $fieldNames[] = $node->name->value; - } - - return $fieldNames; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php index 9308fe3b4866c..2778262ca244b 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php @@ -3,57 +3,104 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -declare(strict_types=1); +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver; use GraphQL\Type\Definition\ResolveInfo; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred\Product as ProductDataProvider; use Magento\Framework\GraphQl\Config\Data\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\Framework\GraphQl\Resolver\Value; use Magento\Framework\GraphQl\Resolver\ValueFactory; +use Magento\CatalogGraphQl\Model\Resolver\Products\Attributes\Collection; /** - * Class Product + * {@inheritdoc} */ class Product implements ResolverInterface { + /** + * @var ProductDataProvider + */ + private $productDataProvider; + /** * @var ValueFactory */ private $valueFactory; + /** + * @var Collection + */ + private $collection; + + /** + * @param ProductDataProvider $productDataProvider + * @param ValueFactory $valueFactory + * @param Collection $collection + */ + public function __construct( + ProductDataProvider $productDataProvider, + ValueFactory $valueFactory, + Collection $collection + ) { + $this->productDataProvider = $productDataProvider; + $this->valueFactory = $valueFactory; + $this->collection = $collection; + } + /** * {@inheritDoc} */ - public function resolve( - Field $field, - array $value = null, - array $args = null, - $context, - ResolveInfo $info - ): ?Value { - if (!isset($value['model'])) { - return null; + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?Value + { + if (!isset($value['sku'])) { + throw new GraphQlInputException(__('No child sku found for product link.')); } + $this->productDataProvider->addProductSku($value['sku']); + $fields = $this->getProductFields($info); + $matchedFields = $this->collection->getRequestAttributes($fields); + $this->productDataProvider->addEavAttributes($matchedFields); $result = function () use ($value) { + $data = $this->productDataProvider->getProductBySkus($value['sku']); + if (!$data) { + return null; + } + $productModel = $data['model']; /** @var \Magento\Catalog\Model\Product $productModel */ - $productModel = $value['model']; - $productData = $productModel->getData(); + $data = $productModel->getData(); + $data['model'] = $productModel; if (!empty($productModel->getCustomAttributes())) { foreach ($productModel->getCustomAttributes() as $customAttribute) { - if (!isset($productData[$customAttribute->getAttributeCode()])) { - $productData[$customAttribute->getAttributeCode()] = $customAttribute->getValue(); + if (!isset($data[$customAttribute->getAttributeCode()])) { + $data[$customAttribute->getAttributeCode()] = $customAttribute->getValue(); } } } - $data = array_replace($value, $productData); - return $data; + return array_replace($value, $data); }; return $this->valueFactory->create($result); } + + /** + * Return field names for all requested product fields. + * + * @param ResolveInfo $info + * @return string[] + */ + private function getProductFields(ResolveInfo $info) + { + $fieldNames = []; + foreach ($info->fieldNodes as $node) { + $fieldNames[] = $node->name->value; + } + + return $fieldNames; + } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php index 0e6094d700ed6..bc026d7e97632 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php @@ -70,21 +70,23 @@ public function getList(SearchCriteriaInterface $searchCriteria, array $attribut $collection = $this->collectionFactory->create(); $this->joinProcessor->process($collection); - foreach ($attributes as $attributeCode) { - $collection->addAttributeToSelect($attributeCode); - } +// foreach ($attributes as $attributeCode) { +// $collection->addAttributeToSelect($attributeCode); +// } + $collection->addAttributeToSelect('*'); $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner'); $collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner'); $this->collectionProcessor->process($searchCriteria, $collection); $count = $collection->getSelectCountSql()->query(); - $collection->addPriceData(); $collection->addWebsiteNamesToResult(); $collection->addTaxPercents(); $collection->addWebsiteNamesToResult(); + $sql = $collection->getSelect()->assemble(); $collection->load(); // Methods that perform extra fetches + $collection->addPriceData(); $collection->addCategoryIds(); $collection->addMediaGalleryData(); $collection->addOptionsToResult(); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php index 58f3a6c5dc2b3..4b246a54b5b72 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Filter.php @@ -58,13 +58,14 @@ public function __construct( */ public function getResult(SearchCriteriaInterface $searchCriteria, ResolveInfo $info) : SearchResult { - $fields = $this->getProductFields($info); - $matchedFields = $this->collection->getRequestAttributes($fields); - $products = $this->productDataProvider->getList($searchCriteria, $matchedFields); +// $fields = $this->getProductFields($info); +// $matchedFields = $this->collection->getRequestAttributes($fields); + $products = $this->productDataProvider->getList($searchCriteria, []); $productArray = []; /** @var \Magento\Catalog\Model\Product $product */ foreach ($products->getItems() as $product) { - $productArray[] = ['model' => $product]; + $productArray[$product->getId()] = $product->getData(); + $productArray[$product->getId()]['model'] = $product; } return $this->searchResultFactory->create($products->getTotalCount(), $productArray); @@ -89,6 +90,7 @@ private function getProductFields(ResolveInfo $info) } foreach ($selection->selectionSet->selections as $itemSelection) { + if ($selection->selection) $fieldNames[] = $itemSelection->name->value; } } diff --git a/app/code/Magento/GroupedProductGraphQl/etc/graphql.xml b/app/code/Magento/GroupedProductGraphQl/etc/graphql.xml index 02ca438eb7f3c..0700b0676159a 100644 --- a/app/code/Magento/GroupedProductGraphQl/etc/graphql.xml +++ b/app/code/Magento/GroupedProductGraphQl/etc/graphql.xml @@ -12,6 +12,6 @@ <type xsi:type="OutputType" name="GroupedProductItem"> <field xsi:type="ScalarOutputField" name="qty" type="Float" description="The quantity of this grouped product item"/> <field xsi:type="ScalarOutputField" name="position" type="Int" description="The relative position of this item compared to the other group items."/> - <field xsi:type="ObjectOutputField" name="product" resolver="Magento\CatalogGraphQl\Model\Resolver\ChildProduct" type="ProductInterface" description="The ProductInterface object, which contains details about this product option"/> + <field xsi:type="ObjectOutputField" name="product" resolver="Magento\CatalogGraphQl\Model\Resolver\Product" type="ProductInterface" description="The ProductInterface object, which contains details about this product option"/> </type> </config> From 70a4f898246fb6d47d6585a9358cd6fbb638d53a Mon Sep 17 00:00:00 2001 From: Carey Sizer <carey@balanceinternet.com.au> Date: Sat, 24 Mar 2018 19:59:58 +1300 Subject: [PATCH 204/668] Added controller integration tests for SchemaRequestProcessor and AsynchronousSchemaRequestProcessor These check that the routing works correctly and that the right schema gets output. --- .../Rest/SchemaRequestProcessorTest.php | 41 +++++++++++++++++ ...AsynchronousSchemaRequestProcessorTest.php | 44 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Webapi/Controller/Rest/SchemaRequestProcessorTest.php create mode 100644 dev/tests/integration/testsuite/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessorTest.php diff --git a/dev/tests/integration/testsuite/Magento/Webapi/Controller/Rest/SchemaRequestProcessorTest.php b/dev/tests/integration/testsuite/Magento/Webapi/Controller/Rest/SchemaRequestProcessorTest.php new file mode 100644 index 0000000000000..034a98e189adc --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Webapi/Controller/Rest/SchemaRequestProcessorTest.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Webapi\Controller\Rest; + +use Magento\TestFramework\TestCase\AbstractController; + +class SchemaRequestProcessorTest extends AbstractController +{ + /** + * Test that the rest controller returns the correct schema response. + * + * @param string $path + * @dataProvider schemaRequestProvider + */ + public function testSchemaRequest($path) + { + $this->dispatch($path); + $schema = $this->getResponse()->getBody(); + + // Check that an HTTP 200 response status is visible in the schema. + $this->assertRegExp('/200 Accepted/', $schema); + } + + /** + * @return array + */ + public function schemaRequestProvider() + { + return [ + ['rest/schema'], + ['rest/schema?services=all'], + ['rest/all/schema?services=all'], + ['rest/default/schema?services=all'], + ['rest/schema?services=all'], + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessorTest.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessorTest.php new file mode 100644 index 0000000000000..9f0d228e034bb --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Controller/Rest/AsynchronousSchemaRequestProcessorTest.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\WebapiAsync\Controller\Rest; + +use Magento\TestFramework\TestCase\AbstractController; + +class AsynchronousSchemaRequestProcessorTest extends AbstractController +{ + /** + * Test that the rest controller returns the correct async schema response. + * + * @param string $path + * @dataProvider schemaRequestProvider + */ + public function testSchemaRequest($path) + { + $this->dispatch($path); + $schema = $this->getResponse()->getBody(); + + // Check that an HTTP 202 response is visible for what is normally an HTTP 200. + $this->assertRegExp('/202 Accepted/', $schema); + + // Make sure that the async interface definition is included in the response. + $this->assertRegExp('/webapi-async-data-async-response-interface/', $schema); + } + + /** + * @return array + */ + public function schemaRequestProvider() + { + return [ + ['rest/async/schema'], + ['rest/async/schema?services=all'], + ['rest/all/async/schema?services=all'], + ['rest/default/async/schema?services=all'], + ['rest/async/schema?services=all'], + ]; + } +} From 4cc3fae9781d2f42c6a392f52dd74650e039c0b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Cie=C5=9Blik?= <p.cieslik@macopedia.pl> Date: Sat, 24 Mar 2018 12:02:20 +0100 Subject: [PATCH 205/668] Update zend-soap #37 Update zend-soap to the version that supports PHP 7.2 - ver. 2.7.0 composer.lock already has zend-soap in version 2.7.0, this information was missing in composer.json. --- composer.json | 2 +- composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 089756a750bda..eac773ffa5e57 100644 --- a/composer.json +++ b/composer.json @@ -78,7 +78,7 @@ "zendframework/zend-server": "^2.6.1", "zendframework/zend-servicemanager": "^2.7.8", "zendframework/zend-session": "^2.7.3", - "zendframework/zend-soap": "^2.6.0", + "zendframework/zend-soap": "^2.7.0", "zendframework/zend-stdlib": "^2.7.7", "zendframework/zend-text": "^2.6.0", "zendframework/zend-uri": "^2.5.1", diff --git a/composer.lock b/composer.lock index 563ed47dd80ed..90eb52e95fca7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "03cd971b78790a885bd0a45354a34d90", + "content-hash": "f5c0c61d6a0bce888692dd5824e6c53f", "packages": [ { "name": "braintree/braintree_php", From 4a6156942e9d3f479d1e8247afa1205157230379 Mon Sep 17 00:00:00 2001 From: Max Bucknell <me@maxbucknell.com> Date: Sat, 24 Mar 2018 12:23:11 +0000 Subject: [PATCH 206/668] magento-engcom/php-7.2-support#93: Update `zendframework/zend-code` - Update `zendframework/zend-code` to `~3.3.0` --- composer.json | 2 +- composer.lock | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index 089756a750bda..79b316e2f3f60 100644 --- a/composer.json +++ b/composer.json @@ -58,7 +58,7 @@ "tubalmartin/cssmin": "4.1.1", "webonyx/graphql-php": "^0.11.1", "zendframework/zend-captcha": "^2.7.1", - "zendframework/zend-code": "~3.1.0", + "zendframework/zend-code": "~3.3.0", "zendframework/zend-config": "^2.6.0", "zendframework/zend-console": "^2.6.0", "zendframework/zend-crypt": "^2.6.0", diff --git a/composer.lock b/composer.lock index 563ed47dd80ed..f955aa9b9d64e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "03cd971b78790a885bd0a45354a34d90", + "content-hash": "e46b0880e79e5d475c8967f840123b51", "packages": [ { "name": "braintree/braintree_php", @@ -2237,27 +2237,27 @@ }, { "name": "zendframework/zend-code", - "version": "3.1.0", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-code.git", - "reference": "2899c17f83a7207f2d7f53ec2f421204d3beea27" + "reference": "6b1059db5b368db769e4392c6cb6cc139e56640d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-code/zipball/2899c17f83a7207f2d7f53ec2f421204d3beea27", - "reference": "2899c17f83a7207f2d7f53ec2f421204d3beea27", + "url": "https://api.github.com/repos/zendframework/zend-code/zipball/6b1059db5b368db769e4392c6cb6cc139e56640d", + "reference": "6b1059db5b368db769e4392c6cb6cc139e56640d", "shasum": "" }, "require": { - "php": "^5.6 || 7.0.0 - 7.0.4 || ^7.0.6", + "php": "^7.1", "zendframework/zend-eventmanager": "^2.6 || ^3.0" }, "require-dev": { "doctrine/annotations": "~1.0", "ext-phar": "*", - "phpunit/phpunit": "^4.8.21", - "squizlabs/php_codesniffer": "^2.5", + "phpunit/phpunit": "^6.2.3", + "zendframework/zend-coding-standard": "^1.0.0", "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "suggest": { @@ -2267,8 +2267,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev", - "dev-develop": "3.2-dev" + "dev-master": "3.2-dev", + "dev-develop": "3.3-dev" } }, "autoload": { @@ -2286,7 +2286,7 @@ "code", "zf2" ], - "time": "2016-10-24T13:23:32+00:00" + "time": "2017-10-20T15:21:32+00:00" }, { "name": "zendframework/zend-config", From caf5b3e7495ce9dcfac9a83e2be8787323dd684a Mon Sep 17 00:00:00 2001 From: Mike Whitby <m.whitby@gmail.com> Date: Sat, 24 Mar 2018 13:21:06 +0000 Subject: [PATCH 207/668] magento/magento2#7816: Customer_account.xml file abused This is in addiiton to magento/magento2#12852 commit 36cac17 - that fix removed the title from being set in the `customer_account.xml` file but the fix seemed to do nothing as the title was always being set in the controller anyway. I've removed from the controller and added to the correct layout file. --- app/code/Magento/Customer/Controller/Account/Index.php | 5 +---- .../Customer/view/frontend/layout/customer_account.xml | 3 +++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Account/Index.php b/app/code/Magento/Customer/Controller/Account/Index.php index f734660fc3a77..2ecf79d35b11f 100644 --- a/app/code/Magento/Customer/Controller/Account/Index.php +++ b/app/code/Magento/Customer/Controller/Account/Index.php @@ -35,9 +35,6 @@ public function __construct( */ public function execute() { - /** @var \Magento\Framework\View\Result\Page $resultPage */ - $resultPage = $this->resultPageFactory->create(); - $resultPage->getConfig()->getTitle()->set(__('My Account')); - return $resultPage; + return $this->resultPageFactory->create(); } } diff --git a/app/code/Magento/Customer/view/frontend/layout/customer_account.xml b/app/code/Magento/Customer/view/frontend/layout/customer_account.xml index ac03fa7d293a4..4224e84972f88 100644 --- a/app/code/Magento/Customer/view/frontend/layout/customer_account.xml +++ b/app/code/Magento/Customer/view/frontend/layout/customer_account.xml @@ -6,6 +6,9 @@ */ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd" label="Customer My Account (All Pages)" design_abstraction="custom"> + <head> + <title>My Account + From 088fb209a99517e3bb26a9fb1c0df912ff7af164 Mon Sep 17 00:00:00 2001 From: magento-engcom-team Date: Tue, 13 Feb 2018 11:14:16 +0200 Subject: [PATCH 208/668] Added Visibility and Status filter to category product grid - automated tests --- .../Category/Edit/Section/ProductGrid.php | 8 ++ .../AssertCategoryProductsGridFilter.php | 99 +++++++++++++++++++ .../Category/CreateCategoryEntityTest.xml | 10 ++ 3 files changed, 117 insertions(+) create mode 100644 dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryProductsGridFilter.php diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/Section/ProductGrid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/Section/ProductGrid.php index 19033094c1fb7..6dd6c6c863da5 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/Section/ProductGrid.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/Section/ProductGrid.php @@ -29,6 +29,14 @@ class ProductGrid extends Grid 'name' => [ 'selector' => '#catalog_category_products_filter_name', ], + 'visibility' => [ + 'selector' => '#catalog_category_products_filter_visibility', + 'input' => 'select', + ], + 'status' => [ + 'selector' => '#catalog_category_products_filter_status', + 'input' => 'select', + ], ]; /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryProductsGridFilter.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryProductsGridFilter.php new file mode 100644 index 0000000000000..2cc67271abca4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryProductsGridFilter.php @@ -0,0 +1,99 @@ +getTreeCategories()->selectCategory($category, true); + $categoryProducts = $category->getDataFieldConfig('category_products')['source']->getProducts(); + $catalogCategoryEdit->getEditForm()->openSection('category_products'); + + foreach ($this->testFilterColumns as $field) { + $this->testGridFilter($categoryProducts, $catalogCategoryEdit, $field); + } + } + + /** + * @param array $categoryProducts + * @param CatalogCategoryEdit $catalogCategoryEdit + * @param string $filterField + */ + private function testGridFilter(array $categoryProducts, CatalogCategoryEdit $catalogCategoryEdit, $filterField) + { + $productsByFilter = []; + foreach ($categoryProducts as $product) { + $filterValue = $product->getData($filterField); + if (!isset($productsByFilter[$filterValue])) { + $productsByFilter[$filterValue] = []; + } + $productsByFilter[$filterValue][] = $product; + } + + $productsFieldset = $catalogCategoryEdit->getEditForm()->getSection('category_products'); + foreach ($productsByFilter as $filterValue => $products) { + $productsFieldset->getProductGrid()->search([ + 'in_category' => 'Yes', + $filterField => $filterValue, + ]); + + $expectedRows = []; + foreach ($products as $product) { + $expectedRows[] = $product->getName(); + } + $gridRows = $productsFieldset->getProductGrid()->getRowsData(['name']); + $actualRows = array_column($gridRows, 'name'); + sort($expectedRows); + sort($actualRows); + + \PHPUnit_Framework_Assert::assertEquals( + $expectedRows, + $actualRows, + "Category products grid filter '$filterField' does not work correctly" + ); + } + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Category products grid filter works correctly'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml index b10a47b63508c..a840b81a5d206 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml @@ -175,5 +175,15 @@ + + addSubcategory + default_category + Yes + Yes + Subcategory%isolation% + catalogProductSimple::default, catalogProductSimple::not_visible_individually + + + From ed7f4e65843b29591c6140db7b88e7225a85cb25 Mon Sep 17 00:00:00 2001 From: Diego Cabrejas Date: Sat, 24 Mar 2018 15:16:45 +0000 Subject: [PATCH 209/668] magento-engcom/php-7.2-support#74: Eliminate usage of Zend_Uri from Magento 2 Open Source - Replacing usages of Zend_Uri classes with Zend Uri clases from ZF-3. - Removed Zend_Uri typehints that were never used, a common pattern I saw was that the Zend_Uri class was typehinted along with a type string but Magento always passes a string to the method so the Zend_Uri could safely be removed. Would be good to know how to run static test to make sure 100%. --- app/code/Magento/Store/Model/Store.php | 3 ++- .../Test/Legacy/_files/obsolete_classes.php | 3 ++- .../Magento/Framework/HTTP/Adapter/Curl.php | 5 +---- .../Magento/Framework/HTTP/ZendClient.php | 2 +- .../Magento/Framework/Oauth/Helper/Request.php | 3 ++- lib/internal/Magento/Framework/Url/Validator.php | 15 ++++++++++----- lib/internal/Magento/Framework/Webapi/Request.php | 2 +- 7 files changed, 19 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Store/Model/Store.php b/app/code/Magento/Store/Model/Store.php index 242ca3a2891c4..bd90bb9f09496 100644 --- a/app/code/Magento/Store/Model/Store.php +++ b/app/code/Magento/Store/Model/Store.php @@ -18,6 +18,7 @@ use Magento\Framework\Url\ScopeInterface as UrlScopeInterface; use Magento\Framework\UrlInterface; use Magento\Store\Api\Data\StoreInterface; +use Zend\Uri\UriFactory; /** * Store model @@ -801,7 +802,7 @@ public function isCurrentlySecure() return false; } - $uri = \Zend_Uri::factory($secureBaseUrl); + $uri = UriFactory::factory($secureBaseUrl); $port = $uri->getPort(); $serverPort = $this->_request->getServer('SERVER_PORT'); $isSecure = $uri->getScheme() == 'https' && isset($serverPort) && $port == $serverPort; diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php index f75f89c05eaec..9fa4b05b41507 100755 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php @@ -4234,5 +4234,6 @@ 'Magento\Elasticsearch\Test\Unit\Model\SearchAdapter\ConnectionManagerTest', 'Magento\Elasticsearch\Test\Unit\SearchAdapter\ConnectionManagerTest' ], - ['Zend_Feed', 'Zend\Feed'] + ['Zend_Feed', 'Zend\Feed'], + ['Zend_Uri', 'Zend\Uri\Uri'] ]; diff --git a/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php b/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php index db466ca30e7eb..15f09b8505202 100644 --- a/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php +++ b/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php @@ -154,7 +154,7 @@ public function connect($host, $port = 80, $secure = false) * Send request to the remote server * * @param string $method - * @param \Zend_Uri_Http|string $url + * @param string $url * @param string $http_ver * @param array $headers * @param string $body @@ -163,9 +163,6 @@ public function connect($host, $port = 80, $secure = false) */ public function write($method, $url, $http_ver = '1.1', $headers = [], $body = '') { - if ($url instanceof \Zend_Uri_Http) { - $url = $url->getUri(); - } $this->_applyConfig(); // set url to post to diff --git a/lib/internal/Magento/Framework/HTTP/ZendClient.php b/lib/internal/Magento/Framework/HTTP/ZendClient.php index f5a001cf8e417..f88e6fabcb6f1 100644 --- a/lib/internal/Magento/Framework/HTTP/ZendClient.php +++ b/lib/internal/Magento/Framework/HTTP/ZendClient.php @@ -21,7 +21,7 @@ class ZendClient extends \Zend_Http_Client protected $_urlEncodeBody = true; /** - * @param null|\Zend_Uri_Http|string $uri + * @param null|string $uri * @param null|array $config */ public function __construct($uri = null, $config = null) diff --git a/lib/internal/Magento/Framework/Oauth/Helper/Request.php b/lib/internal/Magento/Framework/Oauth/Helper/Request.php index 64971dbfb6d18..548c4a5990efe 100644 --- a/lib/internal/Magento/Framework/Oauth/Helper/Request.php +++ b/lib/internal/Magento/Framework/Oauth/Helper/Request.php @@ -6,6 +6,7 @@ namespace Magento\Framework\Oauth\Helper; use Magento\Framework\App\RequestInterface; +use Zend\Uri\UriFactory; class Request { @@ -95,7 +96,7 @@ protected function _processRequest($authHeaderValue, $contentTypeHeader, $reques } $protocolParamsNotSet = !$protocolParams; - $queryString = \Zend_Uri_Http::fromString($requestUrl)->getQuery(); + $queryString = UriFactory::factory($requestUrl)->getQuery(); $this->_extractQueryStringParams($protocolParams, $queryString); if ($protocolParamsNotSet) { diff --git a/lib/internal/Magento/Framework/Url/Validator.php b/lib/internal/Magento/Framework/Url/Validator.php index 3a47e9142b43d..f50ceb897859d 100644 --- a/lib/internal/Magento/Framework/Url/Validator.php +++ b/lib/internal/Magento/Framework/Url/Validator.php @@ -11,6 +11,8 @@ */ namespace Magento\Framework\Url; +use Zend\Uri\UriFactory; + class Validator extends \Zend_Validate_Abstract { /**#@+ @@ -45,11 +47,14 @@ public function isValid($value) { $this->_setValue($value); - if (!\Zend_Uri::check($value)) { - $this->_error(self::INVALID_URL); - return false; - } + try { + $uri = UriFactory::factory($value); + if ($uri->isValid()) { + return true; + } + } catch (Exception $e) {/** left empty */} - return true; + $this->_error(self::INVALID_URL); + return false; } } diff --git a/lib/internal/Magento/Framework/Webapi/Request.php b/lib/internal/Magento/Framework/Webapi/Request.php index 47ab6bc7f994e..3628bfbafb060 100644 --- a/lib/internal/Magento/Framework/Webapi/Request.php +++ b/lib/internal/Magento/Framework/Webapi/Request.php @@ -34,7 +34,7 @@ class Request extends HttpRequest implements RequestInterface * @param StringUtils $converter * @param AreaList $areaList * @param ScopeInterface $configScope - * @param null|string|\Zend_Uri $uri + * @param null|string $uri */ public function __construct( CookieReaderInterface $cookieReader, From 086624407651eaff7e28e3f6cd8d5123ee0ecf16 Mon Sep 17 00:00:00 2001 From: Diego Cabrejas Date: Sat, 24 Mar 2018 13:14:09 +0000 Subject: [PATCH 210/668] magento-engcom/php-7.2-support#67: Eliminate usage of Zend_Mime from Magento 2 Open Source - Add Magento's own Mime class to replace usage of Zend_Mime --- .../Downloadable/Controller/Download.php | 2 +- .../Unit/Controller/Download/LinkTest.php | 4 +-- .../Test/Legacy/_files/obsolete_classes.php | 3 +- lib/internal/Magento/Framework/HTTP/Mime.php | 28 +++++++++++++++++++ 4 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 lib/internal/Magento/Framework/HTTP/Mime.php diff --git a/app/code/Magento/Downloadable/Controller/Download.php b/app/code/Magento/Downloadable/Controller/Download.php index f0bef425d4b45..583b5a33c6b9c 100644 --- a/app/code/Magento/Downloadable/Controller/Download.php +++ b/app/code/Magento/Downloadable/Controller/Download.php @@ -64,7 +64,7 @@ protected function _processDownload($path, $resourceType) $contentDisposition = $helper->getContentDisposition(); if (!$contentDisposition || in_array($contentType, $this->disallowedContentTypes)) { // For security reasons we force browsers to download the file instead of opening it. - $contentDisposition = \Zend_Mime::DISPOSITION_ATTACHMENT; + $contentDisposition = \Magento\Framework\HTTP\Mime::DISPOSITION_ATTACHMENT; } $response->setHeader('Content-Disposition', $contentDisposition . '; filename=' . $fileName); diff --git a/app/code/Magento/Downloadable/Test/Unit/Controller/Download/LinkTest.php b/app/code/Magento/Downloadable/Test/Unit/Controller/Download/LinkTest.php index f2e288d75a40a..7e756c1790a26 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Controller/Download/LinkTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Controller/Download/LinkTest.php @@ -492,8 +492,8 @@ public function linkNotAvailableDataProvider() public function downloadTypesDataProvider() { return [ - ['mimeType' => 'text/html', 'disposition' => \Zend_Mime::DISPOSITION_ATTACHMENT], - ['mimeType' => 'image/jpeg', 'disposition' => \Zend_Mime::DISPOSITION_INLINE], + ['mimeType' => 'text/html', 'disposition' => \Magento\Framework\HTTP\Mime::DISPOSITION_ATTACHMENT], + ['mimeType' => 'image/jpeg', 'disposition' => \Magento\Framework\HTTP\Mime::DISPOSITION_INLINE], ]; } } diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php index f75f89c05eaec..1faf2a5a4aa19 100755 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php @@ -4234,5 +4234,6 @@ 'Magento\Elasticsearch\Test\Unit\Model\SearchAdapter\ConnectionManagerTest', 'Magento\Elasticsearch\Test\Unit\SearchAdapter\ConnectionManagerTest' ], - ['Zend_Feed', 'Zend\Feed'] + ['Zend_Feed', 'Zend\Feed'], + ['Zend_Mime', 'Magento\Framework\HTTP\Mime'], ]; diff --git a/lib/internal/Magento/Framework/HTTP/Mime.php b/lib/internal/Magento/Framework/HTTP/Mime.php new file mode 100644 index 0000000000000..7979fb2b7d10e --- /dev/null +++ b/lib/internal/Magento/Framework/HTTP/Mime.php @@ -0,0 +1,28 @@ + Date: Sat, 24 Mar 2018 15:43:33 +0000 Subject: [PATCH 211/668] magento-engcom/php-7.2-support#94: Remove Zend_Service Dependency from CurrencyInterface --- .../Magento/Framework/CurrencyInterface.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib/internal/Magento/Framework/CurrencyInterface.php b/lib/internal/Magento/Framework/CurrencyInterface.php index 7242a724e05a7..ca042bda849aa 100644 --- a/lib/internal/Magento/Framework/CurrencyInterface.php +++ b/lib/internal/Magento/Framework/CurrencyInterface.php @@ -235,19 +235,4 @@ public function isMore($value, $currency = null); * @return boolean */ public function isLess($value, $currency = null); - - /** - * Returns the set service class - * - * @return \Zend_Service - */ - public function getService(); - - /** - * Sets a new exchange service - * - * @param string|\Magento\Framework\Locale\CurrencyInterface $service Service class - * @return \Magento\Framework\CurrencyInterface - */ - public function setService($service); } From 7a0534ad48dc33f6edb4f162d80ff12aa3759b30 Mon Sep 17 00:00:00 2001 From: Matias Montes Date: Sat, 24 Mar 2018 13:35:13 -0300 Subject: [PATCH 212/668] Fixed decimal handling in order quantities Added test coverage to getSimpleQtyToShip and getQtyToInvoice Fixes 14328 --- app/code/Magento/Sales/Model/Order/Item.php | 4 +- .../Sales/Test/Unit/Model/Order/ItemTest.php | 197 ++++++++++++++++++ 2 files changed, 199 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Item.php b/app/code/Magento/Sales/Model/Order/Item.php index da2a06c2db25a..d2f5f5ce56692 100644 --- a/app/code/Magento/Sales/Model/Order/Item.php +++ b/app/code/Magento/Sales/Model/Order/Item.php @@ -233,7 +233,7 @@ public function getQtyToShip() public function getSimpleQtyToShip() { $qty = $this->getQtyOrdered() - $this->getQtyShipped() - $this->getQtyRefunded() - $this->getQtyCanceled(); - return max($qty, 0); + return max(round($qty, 8), 0); } /** @@ -248,7 +248,7 @@ public function getQtyToInvoice() } $qty = $this->getQtyOrdered() - $this->getQtyInvoiced() - $this->getQtyCanceled(); - return max($qty, 0); + return max(round($qty, 8), 0); } /** diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php index 03a388410f335..bdfc365e25add 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php @@ -235,4 +235,201 @@ public function getProductOptionsDataProvider() ] ]; } + + /** + * Test different combinations of item qty setups + * + * @param array $options + * @param float $expectedResult + * + * @dataProvider getItemQtyVariants + */ + public function testGetSimpleQtyToShip(array $options, $expectedResult) + { + $this->model->setData($options); + $this->assertSame($this->model->getSimpleQtyToShip(), $expectedResult['to_ship']); + } + + /** + * Test different combinations of item qty setups + * + * @param array $options + * @param float $expectedResult + * + * @dataProvider getItemQtyVariants + */ + public function testGetQtyToInvoice(array $options, $expectedResult) + { + $this->model->setData($options); + $this->assertSame($this->model->getQtyToInvoice(), $expectedResult['to_invoice']); + } + + /** + * Provides different combinations of qty options for an item and the + * expected qtys pending shipment and invoice + * + * @return array + */ + public function getItemQtyVariants() + { + return [ + 'empty_item' => [ + 'options' => [ + 'qty_ordered' => 0, + 'qty_invoiced' => 0, + 'qty_refunded' => 0, + 'qty_shipped' => 0, + 'qty_canceled' => 0, + ], + 'expectedResult' => [ + 'to_ship' => 0.0, + 'to_invoice' => 0.0 + ] + ], + 'ordered_item' => [ + 'options' => [ + 'qty_ordered' => 12, + 'qty_invoiced' => 0, + 'qty_refunded' => 0, + 'qty_shipped' => 0, + 'qty_canceled' => 0, + ], + 'expectedResult' => [ + 'to_ship' => 12.0, + 'to_invoice' => 12.0 + ] + ], + 'partially_invoiced' => [ + 'options' => [ + 'qty_ordered' => 12, + 'qty_invoiced' => 4, + 'qty_refunded' => 0, + 'qty_shipped' => 0, + 'qty_canceled' => 0, + ], + 'expectedResult' => [ + 'to_ship' => 12.0, + 'to_invoice' => 8.0 + ] + ], + 'completely_invoiced' => [ + 'options' => [ + 'qty_ordered' => 12, + 'qty_invoiced' => 12, + 'qty_refunded' => 0, + 'qty_shipped' => 0, + 'qty_canceled' => 0, + ], + 'expectedResult' => [ + 'to_ship' => 12.0, + 'to_invoice' => 0.0 + ] + ], + 'partially_invoiced_refunded' => [ + 'options' => [ + 'qty_ordered' => 12, + 'qty_invoiced' => 5, + 'qty_refunded' => 5, + 'qty_shipped' => 0, + 'qty_canceled' => 0, + ], + 'expectedResult' => [ + 'to_ship' => 7.0, + 'to_invoice' => 7.0 + ] + ], + 'partially_refunded' => [ + 'options' => [ + 'qty_ordered' => 12, + 'qty_invoiced' => 12, + 'qty_refunded' => 5, + 'qty_shipped' => 0, + 'qty_canceled' => 0, + ], + 'expectedResult' => [ + 'to_ship' => 7.0, + 'to_invoice' => 0.0 + ] + ], + 'partially_shipped' => [ + 'options' => [ + 'qty_ordered' => 12, + 'qty_invoiced' => 0, + 'qty_refunded' => 0, + 'qty_shipped' => 4, + 'qty_canceled' => 0, + ], + 'expectedResult' => [ + 'to_ship' => 8.0, + 'to_invoice' => 12.0 + ] + ], + 'partially_refunded_partially_shipped' => [ + 'options' => [ + 'qty_ordered' => 12, + 'qty_invoiced' => 12, + 'qty_refunded' => 5, + 'qty_shipped' => 4, + 'qty_canceled' => 0, + ], + 'expectedResult' => [ + 'to_ship' => 3.0, + 'to_invoice' => 0.0 + ] + ], + 'complete' => [ + 'options' => [ + 'qty_ordered' => 12, + 'qty_invoiced' => 12, + 'qty_refunded' => 0, + 'qty_shipped' => 12, + 'qty_canceled' => 0, + ], + 'expectedResult' => [ + 'to_ship' => 0.0, + 'to_invoice' => 0.0 + ] + ], + 'canceled' => [ + 'options' => [ + 'qty_ordered' => 12, + 'qty_invoiced' => 0, + 'qty_refunded' => 0, + 'qty_shipped' => 0, + 'qty_canceled' => 12, + ], + 'expectedResult' => [ + 'to_ship' => 0.0, + 'to_invoice' => 0.0 + ] + ], + 'completely_shipped_using_decimals' => [ + 'options' => [ + 'qty_ordered' => 4.4, + 'qty_invoiced' => 0.4, + 'qty_refunded' => 0.4, + 'qty_shipped' => 4, + 'qty_canceled' => 0, + ], + 'expectedResult' => [ + 'to_ship' => 0.0, + 'to_invoice' => 4.0 + ] + ], + 'completely_invoiced_using_decimals' => [ + 'options' => [ + 'qty_ordered' => 4.4, + 'qty_invoiced' => 4, + 'qty_refunded' => 0, + 'qty_shipped' => 4, + 'qty_canceled' => 0.4, + ], + 'expectedResult' => [ + 'to_ship' => 0.0, + 'to_invoice' => 0.0 + ] + ] + ]; + } + } From a866bb50e3447365f17c3c41e5d4b1c90e59582b Mon Sep 17 00:00:00 2001 From: Mike Whitby Date: Sat, 24 Mar 2018 21:31:51 +0000 Subject: [PATCH 213/668] magento/magento2#13929: Images can't be uploaded using WYSIWYG if media directory is a symlink - Added realpath() to root dir to resolve symlinks - Added tests --- .../App/Filesystem/DirectoryResolverTest.php | 50 ++++++++++++++++--- .../App/Filesystem/DirectoryResolver.php | 4 +- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/App/Filesystem/DirectoryResolverTest.php b/dev/tests/integration/testsuite/Magento/Framework/App/Filesystem/DirectoryResolverTest.php index 278c08fbd2b07..8f1f9e92972e5 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/App/Filesystem/DirectoryResolverTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/App/Filesystem/DirectoryResolverTest.php @@ -24,9 +24,9 @@ class DirectoryResolverTest extends \PHPUnit\Framework\TestCase private $directoryResolver; /** - * @var \Magento\Framework\Filesystem\Directory\WriteInterface + * @var \Magento\Framework\Filesystem */ - private $directory; + private $filesystem; /** * @inheritdoc @@ -36,9 +36,7 @@ protected function setUp() $this->objectManager = Bootstrap::getObjectManager(); $this->directoryResolver = $this->objectManager ->create(\Magento\Framework\App\Filesystem\DirectoryResolver::class); - /** @var \Magento\Framework\Filesystem $filesystem */ - $filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class); - $this->directory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA); + $this->filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class); } /** @@ -46,12 +44,15 @@ protected function setUp() * @param string $directoryConfig * @param bool $expectation * @dataProvider validatePathDataProvider + * @throws \Magento\Framework\Exception\FileSystemException * @magentoAppIsolation enabled * @return void */ public function testValidatePath($path, $directoryConfig, $expectation) { - $path = $this->directory->getAbsolutePath($path); + $directory = $this->filesystem + ->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA); + $path = $directory->getAbsolutePath($path); $this->assertEquals($expectation, $this->directoryResolver->validatePath($path, $directoryConfig)); } @@ -62,10 +63,45 @@ public function testValidatePath($path, $directoryConfig, $expectation) */ public function testValidatePathWithException() { - $path = $this->directory->getAbsolutePath(); + $directory = $this->filesystem + ->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA); + $path = $directory->getAbsolutePath(); $this->directoryResolver->validatePath($path, 'wrong_dir'); } + /** + * @param string $path + * @param string $directoryConfig + * @param bool $expectation + * @dataProvider validatePathDataProvider + * @throws \Magento\Framework\Exception\FileSystemException + * @magentoAppIsolation enabled + * @return void + */ + public function testValidatePathWithSymlink($path, $directoryConfig, $expectation) + { + $directory = $this->filesystem + ->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::PUB); + $driver = $directory->getDriver(); + + $mediaPath = $directory->getAbsolutePath('media'); + $mediaMovedPath = $directory->getAbsolutePath('moved-media'); + + try { + $driver->rename($mediaPath, $mediaMovedPath); + $driver->symlink($mediaMovedPath, $mediaPath); + $this->testValidatePath($path, $directoryConfig, $expectation); + } finally { + // be defensive in case some operations failed + if ($driver->isExists($mediaPath) && $driver->isExists($mediaMovedPath)) { + $driver->deleteFile($mediaPath); + $driver->rename($mediaMovedPath, $mediaPath); + } elseif ($driver->isExists($mediaMovedPath)) { + $driver->rename($mediaMovedPath, $mediaPath); + } + } + } + /** * @return array */ diff --git a/lib/internal/Magento/Framework/App/Filesystem/DirectoryResolver.php b/lib/internal/Magento/Framework/App/Filesystem/DirectoryResolver.php index 4b62476ae8445..2bc76198bf37f 100644 --- a/lib/internal/Magento/Framework/App/Filesystem/DirectoryResolver.php +++ b/lib/internal/Magento/Framework/App/Filesystem/DirectoryResolver.php @@ -39,8 +39,8 @@ public function __construct(DirectoryList $directoryList) public function validatePath($path, $directoryConfig = DirectoryList::MEDIA) { $realPath = realpath($path); - $root = $this->directoryList->getPath($directoryConfig); - + $root = realpath($this->directoryList->getPath($directoryConfig)); + return strpos($realPath, $root) === 0; } } From 06f8e8414a5d001192941b86e50581bb23da61be Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" Date: Sun, 25 Mar 2018 21:34:36 +0300 Subject: [PATCH 214/668] fix request processor matching function canProcess --- .../Rest/SynchronousRequestProcessor.php | 4 +-- .../Rest/AsynchronousRequestProcessor.php | 26 ++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Webapi/Controller/Rest/SynchronousRequestProcessor.php b/app/code/Magento/Webapi/Controller/Rest/SynchronousRequestProcessor.php index 2495f4bb1c168..65d5a47d1f36d 100644 --- a/app/code/Magento/Webapi/Controller/Rest/SynchronousRequestProcessor.php +++ b/app/code/Magento/Webapi/Controller/Rest/SynchronousRequestProcessor.php @@ -18,7 +18,7 @@ */ class SynchronousRequestProcessor implements RequestProcessorInterface { - const PROCESSOR_PATH = "/V\n+/"; + const PROCESSOR_PATH = "/V\d+/"; /** * @var RestResponse @@ -112,7 +112,7 @@ public function process(\Magento\Framework\Webapi\Rest\Request $request) */ public function canProcess(\Magento\Framework\Webapi\Rest\Request $request) { - if (preg_match(self::PROCESSOR_PATH, ltrim($request->getPathInfo(), '/')) === 0) { + if (preg_match(self::PROCESSOR_PATH, ltrim($request->getPathInfo(), '/')) === 1) { return true; } return false; diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php index 5b543808f51a0..2e992fd5a37b9 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php @@ -71,13 +71,7 @@ public function __construct( */ public function process(\Magento\Framework\Webapi\Rest\Request $request) { - $request->setPathInfo( - str_replace( - self::PROCESSOR_PATH, - SynchronousRequestProcessor::PROCESSOR_PATH, - $request->getPathInfo() - ) - ); + $this->changePathInfo($request); try { $entitiesParamsArray = $this->inputParamsResolver->resolve(); @@ -95,12 +89,25 @@ public function process(\Magento\Framework\Webapi\Rest\Request $request) ); $this->response->setStatusCode(RestResponse::STATUS_CODE_202) - ->prepareResponse($responseData); + ->prepareResponse($responseData); } catch (\Exception $e) { $this->response->setException($e); } } + private function changePathInfo(\Magento\Framework\Webapi\Rest\Request $request) + { + preg_match(self::PROCESSOR_PATH, $request->getPathInfo(), $asyncMatches); + preg_match(SynchronousRequestProcessor::PROCESSOR_PATH, $asyncMatches[0], $syncMatches); + $request->setPathInfo( + preg_replace( + self::PROCESSOR_PATH, + $syncMatches[0], + $request->getPathInfo() + ) + ); + } + /** * @param \Magento\Framework\Webapi\Rest\Request $request * @return string @@ -120,9 +127,10 @@ private function getTopicName($request) */ public function canProcess(\Magento\Framework\Webapi\Rest\Request $request) { - if (preg_match(self::PROCESSOR_PATH, ltrim($request->getPathInfo(), '/')) === 0) { + if (preg_match(self::PROCESSOR_PATH, ltrim($request->getPathInfo(), '/')) === 1) { return true; } + return false; } } From 5b58a3424e8896d66c0aff279065943b7e9c35fd Mon Sep 17 00:00:00 2001 From: Matias Montes Date: Sun, 25 Mar 2018 16:41:22 -0300 Subject: [PATCH 215/668] Fixed an empty line at the end of the class and reduced the number of lines in the test provider method --- .../Sales/Test/Unit/Model/Order/ItemTest.php | 136 ++++-------------- 1 file changed, 31 insertions(+), 105 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php index bdfc365e25add..c1f53c3eae45c 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php @@ -275,161 +275,87 @@ public function getItemQtyVariants() return [ 'empty_item' => [ 'options' => [ - 'qty_ordered' => 0, - 'qty_invoiced' => 0, - 'qty_refunded' => 0, - 'qty_shipped' => 0, - 'qty_canceled' => 0, + 'qty_ordered' => 0, 'qty_invoiced' => 0, 'qty_refunded' => 0, 'qty_shipped' => 0, + 'qty_canceled' => 0 ], - 'expectedResult' => [ - 'to_ship' => 0.0, - 'to_invoice' => 0.0 - ] + 'expectedResult' => ['to_ship' => 0.0, 'to_invoice' => 0.0] ], 'ordered_item' => [ 'options' => [ - 'qty_ordered' => 12, - 'qty_invoiced' => 0, - 'qty_refunded' => 0, - 'qty_shipped' => 0, - 'qty_canceled' => 0, + 'qty_ordered' => 12, 'qty_invoiced' => 0, 'qty_refunded' => 0, 'qty_shipped' => 0, + 'qty_canceled' => 0 ], - 'expectedResult' => [ - 'to_ship' => 12.0, - 'to_invoice' => 12.0 - ] + 'expectedResult' => ['to_ship' => 12.0, 'to_invoice' => 12.0] ], 'partially_invoiced' => [ - 'options' => [ - 'qty_ordered' => 12, - 'qty_invoiced' => 4, - 'qty_refunded' => 0, - 'qty_shipped' => 0, + 'options' => ['qty_ordered' => 12, 'qty_invoiced' => 4, 'qty_refunded' => 0, 'qty_shipped' => 0, 'qty_canceled' => 0, ], - 'expectedResult' => [ - 'to_ship' => 12.0, - 'to_invoice' => 8.0 - ] + 'expectedResult' => ['to_ship' => 12.0, 'to_invoice' => 8.0] ], 'completely_invoiced' => [ 'options' => [ - 'qty_ordered' => 12, - 'qty_invoiced' => 12, - 'qty_refunded' => 0, - 'qty_shipped' => 0, + 'qty_ordered' => 12, 'qty_invoiced' => 12, 'qty_refunded' => 0, 'qty_shipped' => 0, 'qty_canceled' => 0, ], - 'expectedResult' => [ - 'to_ship' => 12.0, - 'to_invoice' => 0.0 - ] + 'expectedResult' => ['to_ship' => 12.0, 'to_invoice' => 0.0] ], 'partially_invoiced_refunded' => [ 'options' => [ - 'qty_ordered' => 12, - 'qty_invoiced' => 5, - 'qty_refunded' => 5, - 'qty_shipped' => 0, + 'qty_ordered' => 12, 'qty_invoiced' => 5, 'qty_refunded' => 5, 'qty_shipped' => 0, 'qty_canceled' => 0, ], - 'expectedResult' => [ - 'to_ship' => 7.0, - 'to_invoice' => 7.0 - ] + 'expectedResult' => ['to_ship' => 7.0, 'to_invoice' => 7.0] ], 'partially_refunded' => [ 'options' => [ - 'qty_ordered' => 12, - 'qty_invoiced' => 12, - 'qty_refunded' => 5, - 'qty_shipped' => 0, + 'qty_ordered' => 12, 'qty_invoiced' => 12, 'qty_refunded' => 5, 'qty_shipped' => 0, 'qty_canceled' => 0, ], - 'expectedResult' => [ - 'to_ship' => 7.0, - 'to_invoice' => 0.0 - ] + 'expectedResult' => ['to_ship' => 7.0, 'to_invoice' => 0.0] ], 'partially_shipped' => [ 'options' => [ - 'qty_ordered' => 12, - 'qty_invoiced' => 0, - 'qty_refunded' => 0, - 'qty_shipped' => 4, - 'qty_canceled' => 0, + 'qty_ordered' => 12, 'qty_invoiced' => 0, 'qty_refunded' => 0, 'qty_shipped' => 4, + 'qty_canceled' => 0 ], - 'expectedResult' => [ - 'to_ship' => 8.0, - 'to_invoice' => 12.0 - ] + 'expectedResult' => ['to_ship' => 8.0, 'to_invoice' => 12.0] ], 'partially_refunded_partially_shipped' => [ 'options' => [ - 'qty_ordered' => 12, - 'qty_invoiced' => 12, - 'qty_refunded' => 5, - 'qty_shipped' => 4, - 'qty_canceled' => 0, + 'qty_ordered' => 12, 'qty_invoiced' => 12, 'qty_refunded' => 5, 'qty_shipped' => 4, + 'qty_canceled' => 0 ], - 'expectedResult' => [ - 'to_ship' => 3.0, - 'to_invoice' => 0.0 - ] + 'expectedResult' => ['to_ship' => 3.0, 'to_invoice' => 0.0] ], 'complete' => [ 'options' => [ - 'qty_ordered' => 12, - 'qty_invoiced' => 12, - 'qty_refunded' => 0, - 'qty_shipped' => 12, - 'qty_canceled' => 0, + 'qty_ordered' => 12, 'qty_invoiced' => 12, 'qty_refunded' => 0, 'qty_shipped' => 12, + 'qty_canceled' => 0 ], - 'expectedResult' => [ - 'to_ship' => 0.0, - 'to_invoice' => 0.0 - ] + 'expectedResult' => ['to_ship' => 0.0, 'to_invoice' => 0.0] ], 'canceled' => [ 'options' => [ - 'qty_ordered' => 12, - 'qty_invoiced' => 0, - 'qty_refunded' => 0, - 'qty_shipped' => 0, - 'qty_canceled' => 12, + 'qty_ordered' => 12, 'qty_invoiced' => 0, 'qty_refunded' => 0, 'qty_shipped' => 0, + 'qty_canceled' => 12 ], - 'expectedResult' => [ - 'to_ship' => 0.0, - 'to_invoice' => 0.0 - ] + 'expectedResult' => ['to_ship' => 0.0, 'to_invoice' => 0.0] ], 'completely_shipped_using_decimals' => [ 'options' => [ - 'qty_ordered' => 4.4, - 'qty_invoiced' => 0.4, - 'qty_refunded' => 0.4, - 'qty_shipped' => 4, + 'qty_ordered' => 4.4, 'qty_invoiced' => 0.4, 'qty_refunded' => 0.4, 'qty_shipped' => 4, 'qty_canceled' => 0, ], - 'expectedResult' => [ - 'to_ship' => 0.0, - 'to_invoice' => 4.0 - ] + 'expectedResult' => ['to_ship' => 0.0, 'to_invoice' => 4.0] ], 'completely_invoiced_using_decimals' => [ 'options' => [ - 'qty_ordered' => 4.4, - 'qty_invoiced' => 4, - 'qty_refunded' => 0, - 'qty_shipped' => 4, - 'qty_canceled' => 0.4, + 'qty_ordered' => 4.4, 'qty_invoiced' => 4, 'qty_refunded' => 0, 'qty_shipped' => 4, + 'qty_canceled' => 0.4 ], - 'expectedResult' => [ - 'to_ship' => 0.0, - 'to_invoice' => 0.0 - ] + 'expectedResult' => ['to_ship' => 0.0, 'to_invoice' => 0.0] ] ]; } - } From 3c659994a2aad406af28138a886c6141d134f3ba Mon Sep 17 00:00:00 2001 From: Matias Montes Date: Sun, 25 Mar 2018 16:44:03 -0300 Subject: [PATCH 216/668] Merged to test methods into one. Trying to keep the public method count below 11 --- .../Sales/Test/Unit/Model/Order/ItemTest.php | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php index c1f53c3eae45c..39fffa23dc1ec 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php @@ -244,23 +244,10 @@ public function getProductOptionsDataProvider() * * @dataProvider getItemQtyVariants */ - public function testGetSimpleQtyToShip(array $options, $expectedResult) + public function testGetSimpleQtyToMethods(array $options, $expectedResult) { $this->model->setData($options); $this->assertSame($this->model->getSimpleQtyToShip(), $expectedResult['to_ship']); - } - - /** - * Test different combinations of item qty setups - * - * @param array $options - * @param float $expectedResult - * - * @dataProvider getItemQtyVariants - */ - public function testGetQtyToInvoice(array $options, $expectedResult) - { - $this->model->setData($options); $this->assertSame($this->model->getQtyToInvoice(), $expectedResult['to_invoice']); } From f5aaa2adf0f92428455269359db5b17d0513efef Mon Sep 17 00:00:00 2001 From: Eugene Tulika Date: Sun, 25 Mar 2018 21:23:04 -0500 Subject: [PATCH 217/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - fixed exception handling in Bulk Mass Schedule - added integration test - fixed regexp for Asynchronous Request Processor --- .../Rest/SchemaRequestProcessor.php | 2 +- .../Rest/SynchronousRequestProcessor.php | 4 +- .../Data/AsyncResponse/ItemsListInterface.php | 30 +++ .../Api/Data/AsyncResponseInterface.php | 21 +- .../ItemStatusInterface.php | 3 +- .../Rest/AsynchronousRequestProcessor.php | 51 +++-- .../WebapiAsync/Model/AsyncResponse.php | 18 +- .../Model/AsyncResponse/ItemStatus.php | 2 +- .../Model/AsyncResponse/ItemsList.php | 63 +++++- .../Model/MessageQueue/MassConsumer.php | 13 +- .../Model/MessageQueue/MassSchedule.php | 147 ++++++------ app/code/Magento/WebapiAsync/etc/di.xml | 2 +- .../WebapiAsync/etc/webapi_rest/di.xml | 4 +- .../PublisherConsumerController.php | 18 +- .../UseCase/QueueTestCaseAbstract.php | 12 +- .../Model/MessageQueue/MassScheduleTest.php | 211 ++++++++++++++++++ .../Exception/AbstractAggregateException.php | 7 + .../Framework/Exception/BulkException.php | 56 +++++ 18 files changed, 526 insertions(+), 138 deletions(-) rename app/code/Magento/WebapiAsync/Api/Data/{AsyncResponse => }/ItemStatusInterface.php (96%) create mode 100644 dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/MassScheduleTest.php create mode 100644 lib/internal/Magento/Framework/Exception/BulkException.php diff --git a/app/code/Magento/Webapi/Controller/Rest/SchemaRequestProcessor.php b/app/code/Magento/Webapi/Controller/Rest/SchemaRequestProcessor.php index f1b6237d090f2..a8454e2397216 100644 --- a/app/code/Magento/Webapi/Controller/Rest/SchemaRequestProcessor.php +++ b/app/code/Magento/Webapi/Controller/Rest/SchemaRequestProcessor.php @@ -65,7 +65,7 @@ public function process(\Magento\Framework\Webapi\Rest\Request $request) */ public function canProcess(\Magento\Framework\Webapi\Rest\Request $request) { - if (strpos(ltrim($request->getPathInfo(), '/'), self::PROCESSOR_PATH) === 0) { + if (strpos($request->getPathInfo(), self::PROCESSOR_PATH) === 0) { return true; } return false; diff --git a/app/code/Magento/Webapi/Controller/Rest/SynchronousRequestProcessor.php b/app/code/Magento/Webapi/Controller/Rest/SynchronousRequestProcessor.php index 2495f4bb1c168..fe34a3f928fcd 100644 --- a/app/code/Magento/Webapi/Controller/Rest/SynchronousRequestProcessor.php +++ b/app/code/Magento/Webapi/Controller/Rest/SynchronousRequestProcessor.php @@ -18,7 +18,7 @@ */ class SynchronousRequestProcessor implements RequestProcessorInterface { - const PROCESSOR_PATH = "/V\n+/"; + const PROCESSOR_PATH = "/^\\/V.+/"; /** * @var RestResponse @@ -112,7 +112,7 @@ public function process(\Magento\Framework\Webapi\Rest\Request $request) */ public function canProcess(\Magento\Framework\Webapi\Rest\Request $request) { - if (preg_match(self::PROCESSOR_PATH, ltrim($request->getPathInfo(), '/')) === 0) { + if (preg_match(self::PROCESSOR_PATH, ltrim($request->getPathInfo(), '/')) === 1) { return true; } return false; diff --git a/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemsListInterface.php b/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemsListInterface.php index 7fe73f9b8d4f5..1c29adbb3f8fc 100644 --- a/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemsListInterface.php +++ b/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemsListInterface.php @@ -23,4 +23,34 @@ interface ItemsListInterface * @since 100.3.0 */ public function getItems(); + + /** + * @param $items \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterface[] + * @return \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface + */ + public function setItems($items); + + /** + * @return string + */ + public function getGroupId(); + + /** + * @param $groupId string + * @return \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface + */ + public function setGroupId($groupId); + + /** + * @param bool $isErrors + * @return \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface + */ + public function setIsErrors($isErrors = false); + + /** + * Is there errors during processing bulk + * + * @return boolean + */ + public function getIsErrors(); } diff --git a/app/code/Magento/WebapiAsync/Api/Data/AsyncResponseInterface.php b/app/code/Magento/WebapiAsync/Api/Data/AsyncResponseInterface.php index bc9ba54ca7bf4..e9629316773d5 100644 --- a/app/code/Magento/WebapiAsync/Api/Data/AsyncResponseInterface.php +++ b/app/code/Magento/WebapiAsync/Api/Data/AsyncResponseInterface.php @@ -11,12 +11,12 @@ * Temporary data object to give response from webapi async router * * @api - * @since 100.3.0 */ interface AsyncResponseInterface { const BULK_UUID = 'bulk_uuid'; const REQUEST_ITEMS = 'request_items'; + const IS_ERRORS = 'is_errors'; /** * Gets the bulk uuid. @@ -38,7 +38,7 @@ public function setBulkUuid($bulkUuid); /** * Gets the list of request items with status data. * - * @return \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface + * @return \Magento\WebapiAsync\Api\Data\ItemStatusInterface[] * @since 100.3.0 */ public function getRequestItems(); @@ -46,11 +46,24 @@ public function getRequestItems(); /** * Sets the list of request items with status data. * - * @param \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface $requestItems + * @param \Magento\WebapiAsync\Api\Data\ItemStatusInterface[] $requestItems * @return $this * @since 100.3.0 */ - public function setRequestItems(\Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface $requestItems); + public function setRequestItems($requestItems); + + /** + * @param bool $isErrors + * @return \Magento\WebapiAsync\Api\Data\AsyncResponseInterface + */ + public function setIsErrors($isErrors = false); + + /** + * Is there errors during processing bulk + * + * @return boolean + */ + public function getIsErrors(); /** * Retrieve existing extension attributes object. diff --git a/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemStatusInterface.php b/app/code/Magento/WebapiAsync/Api/Data/ItemStatusInterface.php similarity index 96% rename from app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemStatusInterface.php rename to app/code/Magento/WebapiAsync/Api/Data/ItemStatusInterface.php index 538f29e2f509f..c9a863a0d2fae 100644 --- a/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemStatusInterface.php +++ b/app/code/Magento/WebapiAsync/Api/Data/ItemStatusInterface.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\WebapiAsync\Api\Data\AsyncResponse; +namespace Magento\WebapiAsync\Api\Data; /** * ItemStatusInterface interface @@ -12,7 +12,6 @@ * Indicate if entity param was Accepted|Rejected to bulk schedule * * @api - * @since 100.3.0 */ interface ItemStatusInterface { diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php index 5b543808f51a0..9aed29eb560ab 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php @@ -6,17 +6,18 @@ namespace Magento\WebapiAsync\Controller\Rest; +use Magento\Framework\Exception\BulkException; use Magento\Webapi\Controller\Rest\RequestProcessorInterface; use Magento\Framework\Webapi\Rest\Response as RestResponse; use Magento\WebapiAsync\Controller\Rest\Async\InputParamsResolver; use Magento\WebapiAsync\Model\MessageQueue\MassSchedule; use Magento\WebapiAsync\Model\ConfigInterface as WebApiAsyncConfig; -use Magento\Webapi\Controller\Rest\SynchronousRequestProcessor; use Magento\Framework\Reflection\DataObjectProcessor; +use Magento\WebapiAsync\Api\Data\AsyncResponseInterfaceFactory; class AsynchronousRequestProcessor implements RequestProcessorInterface { - const PROCESSOR_PATH = "/async\\/V\\d+/"; + const PROCESSOR_PATH = "/^\\/async(\\/V.+)/"; /** * @var \Magento\Framework\Webapi\Rest\Response @@ -43,6 +44,11 @@ class AsynchronousRequestProcessor implements RequestProcessorInterface */ private $dataObjectProcessor; + /** + * @var \Magento\WebapiAsync\Api\Data\AsyncResponseInterfaceFactory + */ + private $asyncResponseFactory; + /** * Initialize dependencies. * @@ -51,19 +57,22 @@ class AsynchronousRequestProcessor implements RequestProcessorInterface * @param \Magento\WebapiAsync\Model\MessageQueue\MassSchedule $asyncBulkPublisher * @param \Magento\WebapiAsync\Model\ConfigInterface $webapiAsyncConfig * @param \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor + * @param \Magento\WebapiAsync\Api\Data\AsyncResponseInterfaceFactory $asyncResponse */ public function __construct( RestResponse $response, InputParamsResolver $inputParamsResolver, MassSchedule $asyncBulkPublisher, WebApiAsyncConfig $webapiAsyncConfig, - DataObjectProcessor $dataObjectProcessor + DataObjectProcessor $dataObjectProcessor, + AsyncResponseInterfaceFactory $asyncResponse ) { $this->response = $response; $this->inputParamsResolver = $inputParamsResolver; $this->asyncBulkPublisher = $asyncBulkPublisher; $this->webapiAsyncConfig = $webapiAsyncConfig; $this->dataObjectProcessor = $dataObjectProcessor; + $this->asyncResponseFactory = $asyncResponse; } /** @@ -71,34 +80,32 @@ public function __construct( */ public function process(\Magento\Framework\Webapi\Rest\Request $request) { + $path = $request->getPathInfo(); + $path = preg_replace(self::PROCESSOR_PATH, "$1", $path); $request->setPathInfo( - str_replace( - self::PROCESSOR_PATH, - SynchronousRequestProcessor::PROCESSOR_PATH, - $request->getPathInfo() - ) + $path ); - try { - $entitiesParamsArray = $this->inputParamsResolver->resolve(); - $topicName = $this->getTopicName($request); + $entitiesParamsArray = $this->inputParamsResolver->resolve(); + $topicName = $this->getTopicName($request); + $requestItemsList = null; - /** @var \Magento\WebapiAsync\Api\Data\AsyncResponseInterface $asyncResponse */ + try { $asyncResponse = $this->asyncBulkPublisher->publishMass( $topicName, $entitiesParamsArray ); + } catch (BulkException $bulkException) { + $asyncResponse = $bulkException->getData(); + } - $responseData = $this->dataObjectProcessor->buildOutputDataArray( - $asyncResponse, - \Magento\WebapiAsync\Api\Data\AsyncResponseInterface::class - ); + $responseData = $this->dataObjectProcessor->buildOutputDataArray( + $asyncResponse, + \Magento\WebapiAsync\Api\Data\AsyncResponseInterface::class + ); - $this->response->setStatusCode(RestResponse::STATUS_CODE_202) - ->prepareResponse($responseData); - } catch (\Exception $e) { - $this->response->setException($e); - } + $this->response->setStatusCode(RestResponse::STATUS_CODE_202) + ->prepareResponse($responseData); } /** @@ -120,7 +127,7 @@ private function getTopicName($request) */ public function canProcess(\Magento\Framework\Webapi\Rest\Request $request) { - if (preg_match(self::PROCESSOR_PATH, ltrim($request->getPathInfo(), '/')) === 0) { + if (preg_match(self::PROCESSOR_PATH, $request->getPathInfo()) === 1) { return true; } return false; diff --git a/app/code/Magento/WebapiAsync/Model/AsyncResponse.php b/app/code/Magento/WebapiAsync/Model/AsyncResponse.php index d5cfff5ebed4b..c4ac59ff4ba70 100644 --- a/app/code/Magento/WebapiAsync/Model/AsyncResponse.php +++ b/app/code/Magento/WebapiAsync/Model/AsyncResponse.php @@ -39,11 +39,27 @@ public function getRequestItems() /** * @inheritDoc */ - public function setRequestItems(\Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface $requestItems) + public function setRequestItems($requestItems) { return $this->setData(self::REQUEST_ITEMS, $requestItems); } + /** + * @inheritdoc + */ + public function setIsErrors($isErrors = false) + { + return $this->setData(self::IS_ERRORS, $isErrors); + } + + /** + * @inheritdoc + */ + public function getIsErrors() + { + return $this->getData(self::IS_ERRORS); + } + /** * @inheritDoc */ diff --git a/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemStatus.php b/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemStatus.php index 6f03ddd8440e7..ab34561fcf049 100644 --- a/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemStatus.php +++ b/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemStatus.php @@ -6,7 +6,7 @@ namespace Magento\WebapiAsync\Model\AsyncResponse; -use Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterface; +use Magento\WebapiAsync\Api\Data\ItemStatusInterface; use Magento\Framework\DataObject; class ItemStatus extends DataObject implements ItemStatusInterface diff --git a/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemsList.php b/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemsList.php index c15dad327eab6..3f0e29064e88d 100644 --- a/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemsList.php +++ b/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemsList.php @@ -7,20 +7,53 @@ namespace Magento\WebapiAsync\Model\AsyncResponse; use Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface; +use Magento\WebapiAsync\Api\Data\ItemStatusInterface; class ItemsList implements ItemsListInterface { /** - * @var array + * @var ItemStatusInterface[] */ private $items; /** - * @param array $items [optional] + * @var string */ - public function __construct(array $items = []) + private $groupId; + + /** + * @var bool + */ + private $isErrors; + + /** + * @param $groupId string + * @param ItemStatusInterface[] $items + * @param bool $isError + */ + public function __construct($groupId, array $items = [], $isError = false) { $this->items = $items; + $this->groupId = $groupId; + $this->isErrors = $isError; + } + + /** + * @inheritdoc + */ + public function setItems($items) + { + $this->items = $items; + return $this; + } + + /** + * @inheritdoc + */ + public function setGroupId($groupId) + { + $this->groupId = $groupId; + return $this; } /** @@ -30,4 +63,28 @@ public function getItems() { return $this->items; } + + /** + * @inheritdoc + */ + public function getGroupId() + { + return $this->groupId; + } + + /** + * @inheritdoc + */ + public function setIsErrors($isErrors = false) + { + $this->isErrors = $isErrors; + } + + /** + * @inheritdoc + */ + public function getIsErrors() + { + return $this->isErrors; + } } diff --git a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassConsumer.php b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassConsumer.php index 9d5de50451997..9caeed6a0d0f8 100644 --- a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassConsumer.php +++ b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassConsumer.php @@ -155,7 +155,6 @@ private function getTransactionCallback(QueueInterface $queue) $this->dispatchMessage($message); } else { $queue->reject($message); - return; } @@ -165,7 +164,7 @@ private function getTransactionCallback(QueueInterface $queue) } catch (ConnectionLostException $e) { if ($lock) { $this->resource->getConnection() - ->delete($this->resource->getTableName('queue_lock'), ['id = ?' => $lock->getId()]); + ->delete($this->resource->getTableName('queue_lock'), ['id = ?' => $lock->getId()]); } } catch (NotFoundException $e) { $queue->acknowledge($message); @@ -174,7 +173,7 @@ private function getTransactionCallback(QueueInterface $queue) $queue->reject($message, false, $e->getMessage()); if ($lock) { $this->resource->getConnection() - ->delete($this->resource->getTableName('queue_lock'), ['id = ?' => $lock->getId()]); + ->delete($this->resource->getTableName('queue_lock'), ['id = ?' => $lock->getId()]); } } }; @@ -204,7 +203,7 @@ private function dispatchMessage(EnvelopeInterface $message) $entityParams = $this->messageEncoder->decode($topicName, $data['meta_information']); $this->messageValidator->validate($topicName, $entityParams); } catch (\Exception $e) { - $this->logger->critical($e->getMessage()); + $this->logger->error($e->getMessage()); $status = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED; $errorCode = $e->getCode(); $messages[] = $e->getMessage(); @@ -231,19 +230,19 @@ private function dispatchMessage(EnvelopeInterface $message) __('Sorry, something went wrong during product prices update. Please see log for details.'); } } catch (NoSuchEntityException $e) { - $this->logger->critical($e->getMessage()); + $this->logger->error($e->getMessage()); $status = ($e instanceof TemporaryStateExceptionInterface) ? OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED : OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED; $errorCode = $e->getCode(); $messages[] = $e->getMessage(); } catch (LocalizedException $e) { - $this->logger->critical($e->getMessage()); + $this->logger->error($e->getMessage()); $status = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED; $errorCode = $e->getCode(); $messages[] = $e->getMessage(); } catch (\Exception $e) { - $this->logger->critical($e->getMessage()); + $this->logger->error($e->getMessage()); $status = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED; $errorCode = $e->getCode(); $messages[] = $e->getMessage(); diff --git a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php index a6cec79f58aa3..1ee20d989c829 100644 --- a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php +++ b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php @@ -9,18 +9,18 @@ use Magento\AsynchronousOperations\Api\Data\OperationInterface; use Magento\AsynchronousOperations\Api\Data\OperationInterfaceFactory; use Magento\Framework\DataObject\IdentityGeneratorInterface; -use Magento\Authorization\Model\UserContextInterface; use Magento\Framework\EntityManager\EntityManager; +use Magento\Framework\Exception\LocalizedException; +use Magento\WebapiAsync\Api\Data\ItemStatusInterfaceFactory; +use Magento\WebapiAsync\Api\Data\AsyncResponseInterface; use Magento\WebapiAsync\Api\Data\AsyncResponseInterfaceFactory; -use Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterfaceFactory; -use Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterfaceFactory; -use Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterface; -use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterfaceFactory; +use Magento\WebapiAsync\Api\Data\ItemStatusInterface; use Magento\Framework\MessageQueue\MessageValidator; use Magento\Framework\MessageQueue\MessageEncoder; use Magento\Framework\Bulk\BulkManagementInterface; -use Psr\Log\LoggerInterface; use Magento\Framework\Serialize\Serializer\Json; +use Magento\Framework\Exception\BulkException; +use Psr\Log\LoggerInterface; /** * Class MassPublisher used for encoding topic entities to OperationInterface and publish them. @@ -39,32 +39,22 @@ class MassSchedule private $identityService; /** - * @var \Magento\Authorization\Model\UserContextInterface - */ - private $userContext; - - /** - * @var \Magento\Framework\Serialize\Serializer\Json + * @var Json */ private $jsonSerializer; /** - * @var \Magento\Framework\EntityManager\EntityManager + * @var EntityManager */ private $entityManager; /** - * @var \Magento\WebapiAsync\Api\Data\AsyncResponseInterfaceFactory + * @var AsyncResponseInterfaceFactory */ private $asyncResponseFactory; /** - * @var \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterfaceFactory - */ - private $itemsListInterfaceFactory; - - /** - * @var \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterfaceFactory + * @var ItemStatusInterfaceFactory */ private $itemStatusInterfaceFactory; @@ -83,84 +73,79 @@ class MassSchedule */ private $bulkManagement; + /** + * @var LoggerInterface + */ + private $logger; + /** * Initialize dependencies. * - * @param \Magento\AsynchronousOperations\Api\Data\OperationInterfaceFactory $operationFactory - * @param \Magento\Framework\DataObject\IdentityGeneratorInterface $identityService - * @param \Magento\Authorization\Model\UserContextInterface $userContextInterface - * @param \Magento\Framework\Serialize\Serializer\Json $jsonSerializer - * @param \Magento\Framework\EntityManager\EntityManager $entityManager - * @param \Magento\WebapiAsync\Api\Data\AsyncResponseInterfaceFactory $asyncResponse - * @param \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterfaceFactory $itemsListFactory - * @param \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterfaceFactory $itemStatusFactory - * @param \Magento\Framework\MessageQueue\MessageEncoder $messageEncoder - * @param \Magento\Framework\MessageQueue\MessageValidator $messageValidator - * @param \Magento\Framework\Bulk\BulkManagementInterface $bulkManagement + * @param OperationInterfaceFactory $operationFactory + * @param IdentityGeneratorInterface $identityService + * @param Json $jsonSerializer + * @param EntityManager $entityManager + * @param ItemStatusInterfaceFactory $itemStatusInterfaceFactory + * @param AsyncResponseInterfaceFactory $asyncResponseFactory + * @param MessageEncoder $messageEncoder + * @param MessageValidator $messageValidator + * @param BulkManagementInterface $bulkManagement + * @param LoggerInterface $logger */ public function __construct( OperationInterfaceFactory $operationFactory, IdentityGeneratorInterface $identityService, - UserContextInterface $userContextInterface, Json $jsonSerializer, EntityManager $entityManager, - AsyncResponseInterfaceFactory $asyncResponse, - ItemsListInterfaceFactory $itemsListFactory, - ItemStatusInterfaceFactory $itemStatusFactory, + ItemStatusInterfaceFactory $itemStatusInterfaceFactory, + AsyncResponseInterfaceFactory $asyncResponseFactory, MessageEncoder $messageEncoder, MessageValidator $messageValidator, - BulkManagementInterface $bulkManagement + BulkManagementInterface $bulkManagement, + LoggerInterface $logger ) { - $this->userContext = $userContextInterface; $this->operationFactory = $operationFactory; $this->identityService = $identityService; $this->jsonSerializer = $jsonSerializer; $this->entityManager = $entityManager; - $this->asyncResponseFactory = $asyncResponse; - $this->itemsListInterfaceFactory = $itemsListFactory; - $this->itemStatusInterfaceFactory = $itemStatusFactory; + $this->itemStatusInterfaceFactory = $itemStatusInterfaceFactory; + $this->asyncResponseFactory = $asyncResponseFactory; $this->messageEncoder = $messageEncoder; $this->messageValidator = $messageValidator; $this->bulkManagement = $bulkManagement; + $this->logger = $logger; } /** - * Schedule new bulk operation + * Schedule new bulk operation based on the list of entities * - * @param string $topicName - * @param array $entitiesArray - * @param null|string $groupId - * @throws \Magento\Framework\Exception\LocalizedException - * @return \Magento\WebapiAsync\Api\Data\AsyncResponseInterface + * @param $topicName + * @param $entitiesArray + * @param null $groupId + * @param null $userId + * @return AsyncResponseInterface + * @throws BulkException + * @throws LocalizedException */ - public function publishMass($topicName, $entitiesArray, $groupId = null) + public function publishMass($topicName, array $entitiesArray, $groupId = null, $userId = null) { - $bulkDescription = sprintf('Topic %s', $topicName); - $userId = $this->userContext->getUserId(); - - /** - * set admin userId to 1 because seems it's not work with oAuth - * and we need set user id manually - */ - if (!isset($userId) || $userId == 0) { - $userId = 1; - } + $bulkDescription = __('Topic %s', $topicName); if ($groupId == null) { $groupId = $this->identityService->generateId(); /** create new bulk without operations */ - $this->bulkManagement->scheduleBulk($groupId, [], $bulkDescription, $userId); + if (!$this->bulkManagement->scheduleBulk($groupId, [], $bulkDescription, $userId)) { + throw new LocalizedException( + __('Something went wrong while processing the request.') + ); + } } - /** @var \Magento\WebapiAsync\Api\Data\AsyncResponseInterface $asyncResponse */ - $asyncResponse = $this->asyncResponseFactory->create(); - $asyncResponse->setBulkUuid($groupId); $operations = []; $requestItems = []; - $errors = []; + $bulkException = new BulkException(); foreach ($entitiesArray as $key => $entityParams) { - /** @var \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemStatusInterface $requestItem */ $requestItem = $this->itemStatusInterfaceFactory->create(); try { @@ -188,34 +173,36 @@ public function publishMass($topicName, $entitiesArray, $groupId = null) $requestItem->setStatus(ItemStatusInterface::STATUS_ACCEPTED); $requestItems[] = $requestItem; } catch (\Exception $exception) { + $this->logger->error($exception); $requestItem->setId($key); $requestItem->setStatus(ItemStatusInterface::STATUS_REJECTED); $requestItem->setErrorMessage($exception); $requestItem->setErrorCode($exception); - $errors[] = $requestItem; + $requestItems[] = $requestItem; + $bulkException->addException(new LocalizedException( + __('Error processing input data: %s', $entityParams), + $exception + )); } } - if (!empty($errors)) { - throw new \Magento\Framework\Webapi\Exception( - __('Errors while processing entities'), - 0, - \Magento\Framework\Webapi\Exception::HTTP_BAD_REQUEST, - $errors - ); - } - - $result = $this->bulkManagement->scheduleBulk($groupId, $operations, $bulkDescription, $userId); - - if (!$result) { - throw new \Magento\Framework\Exception\LocalizedException( + if (!$this->bulkManagement->scheduleBulk($groupId, $operations, $bulkDescription, $userId)) { + throw new LocalizedException( __('Something went wrong while processing the request.') ); } - /** @var \Magento\WebapiAsync\Api\Data\AsyncResponse\ItemsListInterface $itemsResponseList */ - $requestItemsList = $this->itemsListInterfaceFactory->create(['items' => $requestItems]); - $asyncResponse->setRequestItems($requestItemsList); + $asyncResponse = $this->asyncResponseFactory->create(); + $asyncResponse->setBulkUuid($groupId); + $asyncResponse->setRequestItems($requestItems); + + if ($bulkException->wasErrorAdded()) { + $asyncResponse->setIsErrors(true); + $bulkException->addData($asyncResponse); + throw $bulkException; + } else { + $asyncResponse->setIsErrors(false); + } return $asyncResponse; } diff --git a/app/code/Magento/WebapiAsync/etc/di.xml b/app/code/Magento/WebapiAsync/etc/di.xml index 3903f1e3487f3..3263266d44fb4 100755 --- a/app/code/Magento/WebapiAsync/etc/di.xml +++ b/app/code/Magento/WebapiAsync/etc/di.xml @@ -8,7 +8,7 @@ - + - + diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php index 2778262ca244b..8c2f0369e3581 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php @@ -65,7 +65,7 @@ public function resolve(Field $field, array $value = null, array $args = null, $ $this->productDataProvider->addEavAttributes($matchedFields); $result = function () use ($value) { - $data = $this->productDataProvider->getProductBySkus($value['sku']); + $data = $this->productDataProvider->getProductBySku($value['sku']); if (!$data) { return null; } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php index 2a5282c63613e..b882150f96382 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php @@ -63,7 +63,6 @@ public function addProductSku(string $sku) : void { if (!in_array($sku, $this->productSkus) && !empty($this->productList)) { $this->productList = []; - $this->productSkus = []; $this->productSkus[] = $sku; } elseif (!in_array($sku, $this->productSkus)) { $this->productSkus[] = $sku; diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php index 8139c4c2aa0f5..fcbc4ff687835 100644 --- a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php +++ b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php @@ -39,6 +39,16 @@ public function resolve( $context, ResolveInfo $info ): ?Value { + if (!isset($value['id'])) { + return null; + } + $this->linksCollection->addParentIdToFilter((int)$value['id']); + + $result = function () use ($value) { + return $this->linksCollection->getGroupedLinksByParentId((int)$value['id']); + }; + + return $this->valueFactory->create($result); } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php index 31d119a52bf14..2140f3fd9d751 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php @@ -126,7 +126,7 @@ private function assertBundleProductOptions($product, $actualResponse) { $this->assertNotEmpty( $actualResponse['items'], - "Precondition failed: 'bundle_product_items' must not be empty" + "Precondition failed: 'bundle product items' must not be empty" ); /** @var OptionList $optionList */ $optionList = ObjectManager::getInstance()->get(\Magento\Bundle\Model\Product\OptionList::class); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/GroupedProduct/GroupedProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/GroupedProduct/GroupedProductViewTest.php index d69e69c11b938..4e7af54cf6fa5 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/GroupedProduct/GroupedProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/GroupedProduct/GroupedProductViewTest.php @@ -59,7 +59,7 @@ private function assertGroupedProductItems($product, $actualResponse) { $this->assertNotEmpty( $actualResponse['items'], - "Precondition failed: 'bundle product items' must not be empty" + "Precondition failed: 'grouped product items' must not be empty" ); $this->assertEquals(2, count($actualResponse['items'])); $groupedProductLinks = $product->getProductLinks(); From d4996ebf219f035839e44f2b0965fc628fb21fdb Mon Sep 17 00:00:00 2001 From: Joan He Date: Mon, 26 Mar 2018 11:29:51 -0500 Subject: [PATCH 230/668] MAGETWO-89260: Fix Travis build issues - fix unit test failure --- .../tests/unit/framework/bootstrap.php | 2 - .../Test/Bootstrap/EnvironmentTest.php | 79 ------------------- 2 files changed, 81 deletions(-) delete mode 100644 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php diff --git a/dev/tests/integration/framework/tests/unit/framework/bootstrap.php b/dev/tests/integration/framework/tests/unit/framework/bootstrap.php index ab3294df72b89..94ca822568be1 100644 --- a/dev/tests/integration/framework/tests/unit/framework/bootstrap.php +++ b/dev/tests/integration/framework/tests/unit/framework/bootstrap.php @@ -9,5 +9,3 @@ require_once $rootDir . '/app/bootstrap.php'; require_once $testsBaseDir . '/framework/autoload.php'; - -ob_start(); diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php deleted file mode 100644 index b6207f309ead9..0000000000000 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Bootstrap/EnvironmentTest.php +++ /dev/null @@ -1,79 +0,0 @@ -_object = new \Magento\TestFramework\Bootstrap\Environment(); - } - - protected function tearDown() - { - $this->_object = null; - } - - /** - * Retrieve the current session's variables - * - * @return array|null - */ - protected function _getSessionVars() - { - return isset($_SESSION) ? $_SESSION : null; - } - - public function testEmulateHttpRequest() - { - $serverVars = $_SERVER; - $this->assertNotEmpty($serverVars); - - $expectedResult = ['HTTP_HOST' => 'localhost', 'SCRIPT_FILENAME' => 'index.php']; - $actualResult = ['HTTP_HOST' => '127.0.0.1']; - $this->_object->emulateHttpRequest($actualResult); - $this->assertEquals($expectedResult, $actualResult); - - $this->assertSame($serverVars, $_SERVER, 'Super-global $_SERVER must not be affected.'); - } - - public function testEmulateSession() - { - $sessionVars = $this->_getSessionVars(); - $this->assertEmpty(session_id()); - - $actualResult = ['session_data_to_be_erased' => 'some_value']; - $this->_object->emulateSession($actualResult); - $this->assertEquals([], $actualResult); - - $this->assertSame($sessionVars, $this->_getSessionVars(), 'Super-global $_SESSION must not be affected.'); - $this->assertNotEmpty(session_id(), 'Global session identified has to be emulated.'); - } -} From 9cb4cd566f0031ecb77bef5de3c24f38131da50e Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" Date: Mon, 26 Mar 2018 20:05:10 +0300 Subject: [PATCH 231/668] fix bulk and single entities params processing in inputParamsResolver for request with url params --- .../Rest/Async/InputParamsResolver.php | 40 +++++++++---------- .../Model/MessageQueue/MassSchedule.php | 3 +- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/Async/InputParamsResolver.php b/app/code/Magento/WebapiAsync/Controller/Rest/Async/InputParamsResolver.php index 9a8232e30a147..524fec7c7ec06 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/Async/InputParamsResolver.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/Async/InputParamsResolver.php @@ -77,9 +77,10 @@ public function __construct( /** * Process and resolve input parameters * Return array with validated input params - * or \Exception object for failed validation params + * or throw \Exception if at least one request entity params is not valid * * @return array + * @throws \Magento\Framework\Exception\InputException if no value is provided for required parameters * @throws \Magento\Framework\Webapi\Exception */ public function resolve() @@ -90,11 +91,13 @@ public function resolve() //simple check if async request have single or bulk entities if (array_key_exists(0, $inputData)) { - foreach ($inputData as $key => $singleParams) { - $webapiResolvedParams[$key] = $this->resolveParams($singleParams); + foreach ($inputData as $key => $singleEntityParams) { + if (is_integer($key)) { + $webapiResolvedParams[$key] = $this->resolveBulkItemParams($singleEntityParams); + } } } else {//single item request - $webapiResolvedParams[] = $this->resolveParams($inputData); + $webapiResolvedParams[] = $this->inputParamsResolver->resolve(); } return $webapiResolvedParams; @@ -109,29 +112,24 @@ public function getRoute() } /** - * @return array|\Exception + * Convert the input array from key-value format to a list of parameters + * suitable for the specified class / method. + * + * Instead of \Magento\Webapi\Controller\Rest\InputParamsResolver + * we don't need to merge body params with url params and use only body params + * + * @param array $inputData data to send to method in key-value format + * @return array list of parameters that can be used to call the service method + * @throws \Magento\Framework\Exception\InputException if no value is provided for required parameters + * @throws \Magento\Framework\Webapi\Exception */ - private function resolveParams($inputData) + private function resolveBulkItemParams($inputData) { $route = $this->getRoute(); $serviceMethodName = $route->getServiceMethod(); $serviceClassName = $route->getServiceClass(); - - /* - * Valid only for updates using PUT when passing id value both in URL and body - */ - if ($this->request->getHttpMethod() == RestRequest::HTTP_METHOD_PUT) { - $inputData = $this->paramsOverrider->overrideRequestBodyIdWithPathParam( - $this->request->getParams(), - $inputData, - $serviceClassName, - $serviceMethodName - ); - $inputData = array_merge($inputData, $this->request->getParams()); - } - - $inputData = $this->paramsOverrider->override($inputData, $route->getParameters()); $inputParams = $this->serviceInputProcessor->process($serviceClassName, $serviceMethodName, $inputData); + return $inputParams; } } diff --git a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php index b6fdde751cc30..3f0f163f61a89 100644 --- a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php +++ b/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php @@ -146,6 +146,7 @@ public function publishMass($topicName, array $entitiesArray, $groupId = null, $ $requestItems = []; $bulkException = new BulkException(); foreach ($entitiesArray as $key => $entityParams) { + /** @var \Magento\WebapiAsync\Api\Data\ItemStatusInterface $requestItem */ $requestItem = $this->itemStatusInterfaceFactory->create(); try { @@ -191,7 +192,7 @@ public function publishMass($topicName, array $entitiesArray, $groupId = null, $ __('Something went wrong while processing the request.') ); } - + /** @var \Magento\WebapiAsync\Api\Data\AsyncResponseInterface $asyncResponse */ $asyncResponse = $this->asyncResponseFactory->create(); $asyncResponse->setBulkUuid($groupId); $asyncResponse->setRequestItems($requestItems); From 74df32bb9957b9ccda8246b3f666c9a1d8e0dd1e Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" Date: Mon, 26 Mar 2018 20:25:58 +0300 Subject: [PATCH 232/668] remove test consumer from queue_consumer.xml and binding from queue_topology.xml --- app/code/Magento/WebapiAsync/etc/queue_consumer.xml | 4 ---- app/code/Magento/WebapiAsync/etc/queue_topology.xml | 1 - 2 files changed, 5 deletions(-) diff --git a/app/code/Magento/WebapiAsync/etc/queue_consumer.xml b/app/code/Magento/WebapiAsync/etc/queue_consumer.xml index a9cb5a5c15443..a0c123847bc47 100644 --- a/app/code/Magento/WebapiAsync/etc/queue_consumer.xml +++ b/app/code/Magento/WebapiAsync/etc/queue_consumer.xml @@ -9,8 +9,4 @@ xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/consumer.xsd"> - - \ No newline at end of file diff --git a/app/code/Magento/WebapiAsync/etc/queue_topology.xml b/app/code/Magento/WebapiAsync/etc/queue_topology.xml index 7dd9ca6e34454..9e4ac909c2261 100644 --- a/app/code/Magento/WebapiAsync/etc/queue_topology.xml +++ b/app/code/Magento/WebapiAsync/etc/queue_topology.xml @@ -8,6 +8,5 @@ - From 032778439c2cd2682d645d813769e81926a2e3ea Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" Date: Mon, 26 Mar 2018 20:32:43 +0300 Subject: [PATCH 233/668] fix SchemaRequestProcessor::canProcess() method --- .../Magento/Webapi/Controller/Rest/SchemaRequestProcessor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Webapi/Controller/Rest/SchemaRequestProcessor.php b/app/code/Magento/Webapi/Controller/Rest/SchemaRequestProcessor.php index a8454e2397216..f1b6237d090f2 100644 --- a/app/code/Magento/Webapi/Controller/Rest/SchemaRequestProcessor.php +++ b/app/code/Magento/Webapi/Controller/Rest/SchemaRequestProcessor.php @@ -65,7 +65,7 @@ public function process(\Magento\Framework\Webapi\Rest\Request $request) */ public function canProcess(\Magento\Framework\Webapi\Rest\Request $request) { - if (strpos($request->getPathInfo(), self::PROCESSOR_PATH) === 0) { + if (strpos(ltrim($request->getPathInfo(), '/'), self::PROCESSOR_PATH) === 0) { return true; } return false; From 18b5bd3c0689290f7625da99d061d29183e299f8 Mon Sep 17 00:00:00 2001 From: Eric Bohanon Date: Mon, 26 Mar 2018 13:36:40 -0500 Subject: [PATCH 234/668] MAGETWO-88936: Grouped products - Fix functional tests --- .../DataProvider/Deferred/Product.php | 1 - .../Model/Resolver/GroupedItems.php | 51 +++++++-- .../Resolver/Products/Links/Collection.php | 102 ------------------ 3 files changed, 44 insertions(+), 110 deletions(-) delete mode 100644 app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Links/Collection.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php index b882150f96382..fb88c6eaf61f3 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Deferred/Product.php @@ -80,7 +80,6 @@ public function addProductSkus(array $skus) : void foreach ($skus as $sku) { if (!in_array($sku, $this->productSkus) && !empty($this->productList)) { $this->productList = []; - $this->productSkus = []; $this->productSkus[] = $sku; } elseif (!in_array($sku, $this->productSkus)) { $this->productSkus[] = $sku; diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php index fcbc4ff687835..6d957ad44bae4 100644 --- a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php +++ b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php @@ -8,11 +8,12 @@ namespace Magento\GroupedProductGraphQl\Model\Resolver; use GraphQL\Type\Definition\ResolveInfo; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred\Product; use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\Framework\GraphQl\Resolver\Value; use Magento\Framework\GraphQl\Resolver\ValueFactory; -use Magento\GroupedProductGraphQl\Model\Resolver\Products\Links\Collection; +use Magento\GroupedProduct\Model\Product\Initialization\Helper\ProductLinks\Plugin\Grouped; /** * {@inheritdoc} @@ -25,9 +26,21 @@ class GroupedItems implements ResolverInterface private $valueFactory; /** - * @var Collection + * @var Product */ - private $linksCollection; + private $productResolver; + + /** + * @param ValueFactory $valueFactory + * @param Product $productResolver + */ + public function __construct( + ValueFactory $valueFactory, + Product $productResolver + ) { + $this->valueFactory = $valueFactory; + $this->productResolver = $productResolver; + } /** * {@inheritDoc} @@ -39,14 +52,38 @@ public function resolve( $context, ResolveInfo $info ): ?Value { - if (!isset($value['id'])) { + if (!isset($value['model'])) { return null; } - $this->linksCollection->addParentIdToFilter((int)$value['id']); + /** @var \Magento\Catalog\Model\Product $productModel */ + $productModel = $value['model']; + $links = $productModel->getProductLinks(); + $linkedSkus = []; + foreach ($links as $link) { + if ($link->getLinkType() !== Grouped::TYPE_NAME) { + continue; + } + + $linkedSkus[] = $link->getLinkedProductSku(); + $data[$link->getLinkedProductSku()] = [ + 'position' => (int)$link->getPosition(), + 'qty' => $link->getExtensionAttributes()->getQty() + ]; + } + + $this->productResolver->addProductSkus($linkedSkus); + + $result = function () use ($value, $linkedSkus, $data) { + foreach ($linkedSkus as $linkedSku) { + $fetchedData = $this->productResolver->getProductBySku($linkedSku); + /** @var \Magento\Catalog\Model\Product $linkedProduct */ + $linkedProduct = $fetchedData['model']; + $data[$linkedProduct->getSku()]['product'] = ['model' => $linkedProduct]; + $data[$linkedProduct->getSku()]['sku'] = $linkedProduct->getSku(); + } - $result = function () use ($value) { - return $this->linksCollection->getGroupedLinksByParentId((int)$value['id']); + return $data; }; return $this->valueFactory->create($result); diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Links/Collection.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Links/Collection.php deleted file mode 100644 index 5e0bda881bacf..0000000000000 --- a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Links/Collection.php +++ /dev/null @@ -1,102 +0,0 @@ -parentIds)) { - $this->parentIds[] = $productId; - } - } - - /** - * Get array of children association links for a passed in grouped product id - * - * @param int $productId - * @return array|null - */ - public function getGroupedLinksByParentId(int $productId) : ?array - { - $groupedLinks = $this->fetch(); - - if (!isset($groupedLinks[$productId])) { - return null; - } - - return $groupedLinks[$productId]; - } - - /** - * Fetch map of associated grouped products - * - * @return array - */ - private function fetch() : array - { - if (empty($this->parentIds) || !empty($this->groupedLinkMap)) { - return $this->groupedLinkMap; - } - - $collection = $this->link - ->setLinkTypeId(\Magento\GroupedProduct\Model\ResourceModel\Product\Link::LINK_TYPE_GROUPED) - ->getProductCollection(); - $collection - ->setFlag('product_children', true) - ->setIsStrongMode() - ->addProductFilter($this->parentIds) - ->addStoreFilter($this->storeManager->getStore()->getId()) - ->addFilterByRequiredOptions() - ->setPositionOrder(); - - /** @var \Magento\Catalog\Model\Product $item */ - foreach ($collection as $item) { - $this->groupedLinkMap[$item->getParentId()][$item->getId()] - = [ - 'qty' => $item->getQty(), - 'position' => (int)$item->getPosition(), - 'sku' => $item->getSku() - ]; - } - - return $this->groupedLinkMap; - } -} From c9800e0ccd73a2c7cc8f1d6d1260524e52b6f971 Mon Sep 17 00:00:00 2001 From: Eric Bohanon Date: Mon, 26 Mar 2018 14:17:52 -0500 Subject: [PATCH 235/668] MAGETWO-88936: Fix configurable product functional tests --- .../Model/Resolver/ConfigurableVariant.php | 29 ++++++++++++++----- .../Model/Resolver/Options.php | 21 ++++++++++---- .../Model/Variant/Collection.php | 15 ++-------- .../etc/graphql.xml | 2 +- 4 files changed, 40 insertions(+), 27 deletions(-) diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/ConfigurableVariant.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/ConfigurableVariant.php index 1f8333e1a594a..bff02e163abcc 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/ConfigurableVariant.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/ConfigurableVariant.php @@ -8,7 +8,10 @@ namespace Magento\ConfigurableProductGraphQl\Model\Resolver; use GraphQL\Type\Definition\ResolveInfo; +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Model\Product; use Magento\ConfigurableProduct\Model\Product\Type\Configurable as Type; +use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\GraphQl\Config\Data\Field; use Magento\ConfigurableProductGraphQl\Model\Variant\Collection; use Magento\Framework\GraphQl\Resolver\ResolverInterface; @@ -42,22 +45,30 @@ class ConfigurableVariant implements ResolverInterface */ private $attributeCollection; + /** + * @var MetadataPool + */ + private $metadataPool; + /** * @param Collection $variantCollection * @param OptionCollection $optionCollection * @param ValueFactory $valueFactory * @param AttributeCollection $attributeCollection + * @param MetadataPool $metadataPool */ public function __construct( Collection $variantCollection, OptionCollection $optionCollection, ValueFactory $valueFactory, - AttributeCollection $attributeCollection + AttributeCollection $attributeCollection, + MetadataPool $metadataPool ) { $this->variantCollection = $variantCollection; $this->optionCollection = $optionCollection; $this->valueFactory = $valueFactory; $this->attributeCollection = $attributeCollection; + $this->metadataPool = $metadataPool; } /** @@ -67,22 +78,24 @@ public function __construct( */ public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?Value { - if ($value['type_id'] !== Type::TYPE_CODE || !isset($value['id'])) { + $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); + if ($value['type_id'] !== Type::TYPE_CODE || !isset($value[$linkField])) { return null; } - $this->variantCollection->addParentId((int)$value['id']); + $this->variantCollection->addParentId((int)$value[$linkField]); $fields = $this->getProductFields($info); $matchedFields = $this->attributeCollection->getRequestAttributes($fields); $this->variantCollection->addEavAttributes($matchedFields); - $this->optionCollection->addProductId((int)$value['id']); + $this->optionCollection->addProductId((int)$value[$linkField]); - $result = function () use ($value) { - $children = $this->variantCollection->getChildProductsByParentId((int)$value['id']) ?: []; - $options = $this->optionCollection->getAttributesByProductId((int)$value['id']) ?: []; + $result = function () use ($value, $linkField) { + $children = $this->variantCollection->getChildProductsByParentId((int)$value[$linkField]) ?: []; + $options = $this->optionCollection->getAttributesByProductId((int)$value[$linkField]) ?: []; $variants = []; + /** @var Product $child */ foreach ($children as $key => $child) { - $variants[$key] = ['product' => $child, 'options' => $options]; + $variants[$key] = ['sku' => $child['sku'], 'product' => $child, 'options' => $options]; } return $variants; diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Options.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Options.php index 75387a1f4b59b..851d43369f892 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Options.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Options.php @@ -8,7 +8,9 @@ namespace Magento\ConfigurableProductGraphQl\Model\Resolver; use GraphQL\Type\Definition\ResolveInfo; +use Magento\Catalog\Api\Data\ProductInterface; use Magento\ConfigurableProduct\Model\Product\Type\Configurable as Type; +use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Resolver\ResolverInterface; use Magento\Framework\GraphQl\Resolver\Value; @@ -30,16 +32,24 @@ class Options implements ResolverInterface */ private $valueFactory; + /** + * @var MetadataPool + */ + private $metadataPool; + /** * @param OptionCollection $optionCollection * @param ValueFactory $valueFactory + * @param MetadataPool $metadataPool */ public function __construct( OptionCollection $optionCollection, - ValueFactory $valueFactory + ValueFactory $valueFactory, + MetadataPool $metadataPool ) { $this->optionCollection = $optionCollection; $this->valueFactory = $valueFactory; + $this->metadataPool = $metadataPool; } /** @@ -49,14 +59,15 @@ public function __construct( */ public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?Value { - if ($value['type_id'] !== Type::TYPE_CODE || !isset($value['id'])) { + $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); + if ($value['type_id'] !== Type::TYPE_CODE || !isset($value[$linkField])) { return null; } - $this->optionCollection->addProductId((int)$value['id']); + $this->optionCollection->addProductId((int)$value[$linkField]); - $result = function () use ($value) { - return $this->optionCollection->getAttributesByProductId((int)$value['id']) ?: []; + $result = function () use ($value, $linkField) { + return $this->optionCollection->getAttributesByProductId((int)$value[$linkField]) ?: []; }; return $this->valueFactory->create($result); diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Variant/Collection.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Variant/Collection.php index 7382a9455f193..31d00d48bc411 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Variant/Collection.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Variant/Collection.php @@ -144,20 +144,9 @@ private function fetch() : array $childCollection->setProductFilter($product); } - $childIds = []; - foreach ($childCollection->getItems() as $childProduct) { - $childIds[] = (int)$childProduct->getData($linkField); - } - - $this->searchCriteriaBuilder->addFilter($linkField, $childIds, 'in'); - $childProducts = $this->productDataProvider->getList( - $this->searchCriteriaBuilder->create(), - $this->attributeCodes - ); - /** @var Product $childProduct */ - foreach ($childProducts->getItems() as $childProduct) { - $formattedChild = ['model' => $childProduct]; + foreach ($childCollection->getItems() as $childProduct) { + $formattedChild = ['model' => $childProduct, 'sku' => $childProduct->getSku()]; $parentId = (int)$childProduct->getParentId(); if (!isset($this->childrenMap[$parentId])) { $this->childrenMap[$parentId] = []; diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml index de594a0734f96..207827939e2e1 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml +++ b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql.xml @@ -13,7 +13,7 @@ - + From 99ed382b18e4eb96b3816f2fb28aa694d1acf0fd Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Mon, 26 Mar 2018 15:13:31 -0500 Subject: [PATCH 236/668] MAGETWO-89292: Implement SDL from prototype - fixing various types and method comments and method signatures --- .../ContentTypeProcessor.php | 2 +- .../HttpHeaderProcessor/StoreProcessor.php | 2 +- app/code/Magento/GraphQl/etc/di.xml | 2 +- .../Argument/Filter/ConnectiveFactory.php | 5 +- .../GraphQl/Argument/Filter/Operator.php | 4 +- .../SearchCriteria/ArgumentApplier/Sort.php | 2 +- .../GraphQl/Config/Data/Argument.php | 16 +++--- .../GraphQl/Config/Data/DataFactory.php | 2 +- .../Framework/GraphQl/Config/Data/Field.php | 2 +- .../GraphQl/Config/GraphQlReader.php | 4 +- .../GraphQlReader/MetaReader/DocReader.php | 4 +- .../MetaReader/FieldMetaReader.php | 33 +++++++----- .../MetaReader/ImplementsReader.php | 42 +++++++++++++++ ...taReader.php => TypeMetaWrapperReader.php} | 15 ++++-- .../Config/GraphQlReader/Reader/EnumType.php | 8 +-- .../GraphQlReader/Reader/InputObjectType.php | 21 ++++---- .../GraphQlReader/Reader/InterfaceType.php | 6 +-- .../GraphQlReader/Reader/ObjectType.php | 51 +++++++------------ .../GraphQl/HttpHeaderProcessorInterface.php | 4 +- .../GraphQl/HttpRequestProcessor.php | 2 +- .../GraphQl/Type/Input/InputMapper.php | 10 ++-- .../ElementMapper/Formatter/Interfaces.php | 11 +--- .../Framework/GraphQl/Type/SchemaFactory.php | 2 +- 23 files changed, 144 insertions(+), 106 deletions(-) create mode 100644 lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/ImplementsReader.php rename lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/{TypeMetaReader.php => TypeMetaWrapperReader.php} (71%) diff --git a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php index f035b41744a28..640a375412f04 100644 --- a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php +++ b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php @@ -21,7 +21,7 @@ class ContentTypeProcessor implements HttpHeaderProcessorInterface * {@inheritDoc} * @throws LocalizedException */ - public function processHeaderValue($headerValue) : void + public function processHeaderValue(string $headerValue) : void { if (!$headerValue || strpos($headerValue, 'application/json') === false) { throw new LocalizedException( diff --git a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php index e54d22a923c8a..027147a0330b2 100644 --- a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php +++ b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php @@ -37,7 +37,7 @@ public function __construct(StoreManagerInterface $storeManager) * {@inheritDoc} * @throws NoSuchEntityException */ - public function processHeaderValue($headerValue) : void + public function processHeaderValue(string $headerValue) : void { if ($headerValue) { $storeCode = ltrim(rtrim($headerValue)); diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 2e793fab34707..215148f1420bc 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -87,7 +87,7 @@ Magento\Framework\GraphQl\Config\GraphQlReader\Reader\EnumType Magento\Framework\GraphQl\Config\GraphQlReader\Reader\ObjectType - Magento\Framework\GraphQl\Config\GraphQlReader\Reader\InputObjectType + Magento\Framework\GraphQl\Config\GraphQlReader\Reader\InputObjectType Magento\Framework\GraphQl\Config\GraphQlReader\Reader\InterfaceType diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/ConnectiveFactory.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/ConnectiveFactory.php index 71adc94e9bb29..75d4e99c98493 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/ConnectiveFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/ConnectiveFactory.php @@ -42,7 +42,10 @@ public function create( Connective::class, [ 'conditions' => $conditions, - 'operator' => new Operator($operator) + 'operator' => $this->objectManager->create( + Operator::class, + ['value' => $operator ?: Operator::AND] + ) ] ); } diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Operator.php b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Operator.php index 711ff66653a72..ff45cd0100f4f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Operator.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/Filter/Operator.php @@ -37,10 +37,10 @@ class Operator private $value; /** - * @param string $value + * @param string|null $value * @throws \Magento\Framework\GraphQl\Exception\GraphQlInputException */ - public function __construct($value = self::AND) + public function __construct(string $value = null) { if (!$value) { $value = self::AND; diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php index a2a4f3fd4f277..25e1613400162 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/SearchCriteria/ArgumentApplier/Sort.php @@ -27,7 +27,7 @@ class Sort implements ArgumentApplierInterface /** * @param SortOrderBuilder|null $sortOrderBuilder */ - public function __construct($sortOrderBuilder = null) + public function __construct(SortOrderBuilder $sortOrderBuilder = null) { $this->sortOrderBuilder = $sortOrderBuilder ?: ObjectManager::getInstance() ->get(SortOrderBuilder::class); diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php index 5a61787414695..70231d121f919 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Argument.php @@ -52,7 +52,7 @@ class Argument implements FieldInterface /** * @var string|null */ - private $default; + private $defaultValue; /** * @param string $name @@ -61,9 +61,9 @@ class Argument implements FieldInterface * @param string $description * @param bool $required * @param bool $isList - * @param $itemType $itemType + * @param string $itemType * @param bool $itemsRequired - * @param string $default + * @param string $defaultValue */ public function __construct( string $name, @@ -74,7 +74,7 @@ public function __construct( bool $isList, string $itemType = '', bool $itemsRequired = false, - string $default = null + string $defaultValue = null ) { $this->name = $name; $this->type = $isList ? $itemType : $type; @@ -83,7 +83,7 @@ public function __construct( $this->required = $required; $this->isList = $isList; $this->itemsRequired = $itemsRequired; - $this->default = $default; + $this->defaultValue = $defaultValue; } /** @@ -157,12 +157,12 @@ public function getDescription() : string } /** - * Return default if argument is a scalar and has a configured default. Otherwise return an empty string. + * Return defaultValue if argument is a scalar and has a configured defaultValue. Otherwise return an empty string. * * @return string|null */ - public function getDefault() : ?string + public function getDefaultValue() : ?string { - return $this->default; + return $this->defaultValue; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php index bb95b2f5223d8..1284498a64a36 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/DataFactory.php @@ -81,7 +81,7 @@ public function createArgument( 'isList' => isset($argumentData['itemType']), 'itemType' => isset($argumentData['itemType']) ? $argumentData['itemType'] : '', 'itemsRequired' => isset($argumentData['itemsRequired']) ? $argumentData['itemsRequired'] : false, - 'default' => isset($argumentData['default']) ? $argumentData['default'] : null + 'defaultType' => isset($argumentData['defaultType']) ? $argumentData['defaultType'] : null ] ); } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php b/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php index 177f554de2fba..9f0c0008611cb 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Data/Field.php @@ -51,7 +51,7 @@ class Field implements OutputFieldInterface * @param string $type * @param bool $required * @param bool $isList - * @param $itemType $itemType + * @param string $itemType * @param string $resolver * @param string $description * @param array $arguments diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php index 1f20383169cc0..d2700c44ff0fe 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php @@ -27,7 +27,6 @@ class GraphQlReader implements ReaderInterface */ private $typeReader; - /** * @var string */ @@ -88,7 +87,6 @@ public function read($scope = null) : array return $results; } - /** * Extract types as string from schema as string * @@ -124,7 +122,7 @@ private function readPartialTypes(string $graphQlSchemaContent) : array * @param string $graphQlSchemaContent * @return string[] [$typeName => $typeDeclaration, ...] */ - private function parseTypes($graphQlSchemaContent) : array + private function parseTypes(string $graphQlSchemaContent) : array { $typeKindsPattern = '(type|interface|union|enum|input)'; $typeNamePattern = '([_A-Za-z][_0-9A-Za-z]+)'; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/DocReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/DocReader.php index bff4634ca5afa..0f647fd111770 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/DocReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/DocReader.php @@ -8,7 +8,7 @@ namespace Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader; /** - * Reads documentation from a AST node + * Reads documentation from the annotation @doc of an AST node */ class DocReader { @@ -18,7 +18,7 @@ class DocReader * @param \GraphQL\Language\AST\NodeList $directives * @return string|null */ - public function readTypeDescription(\GraphQL\Language\AST\NodeList $directives) : ?string + public function read(\GraphQL\Language\AST\NodeList $directives) : ?string { foreach ($directives as $directive) { if ($directive->name->value == 'doc') { diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php index c96d7c9e9346a..f4ef3dd51c0f9 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php @@ -7,10 +7,15 @@ namespace Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader; +use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\TypeMetaWrapperReader; + +/** + * Reads fields and possible arguments from a meta field + */ class FieldMetaReader { /** - * @var TypeMetaReader + * @var TypeMetaWrapperReader */ private $typeMetaReader; @@ -20,20 +25,22 @@ class FieldMetaReader private $docReader; /** - * @param TypeMetaReader $typeMetaReader + * @param TypeMetaWrapperReader $typeMetaReader * @param DocReader $docReader */ - public function __construct(TypeMetaReader $typeMetaReader, DocReader $docReader) + public function __construct(TypeMetaWrapperReader $typeMetaReader, DocReader $docReader) { $this->typeMetaReader = $typeMetaReader; $this->docReader = $docReader; } /** + * Read field and possible arguments from a field meta + * * @param \GraphQL\Type\Definition\FieldDefinition $fieldMeta * @return array */ - public function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) : array + public function read(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) : array { $fieldName = $fieldMeta->name; $fieldTypeMeta = $fieldMeta->getType(); @@ -42,18 +49,18 @@ public function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMet 'arguments' => [] ]; - $fieldResolver = $this->readFieldResolver($fieldMeta); + $fieldResolver = $this->getFieldResolver($fieldMeta); if ($fieldResolver) { $result['resolver'] = $fieldResolver; } $result = array_merge( $result, - $this->typeMetaReader->readTypeMeta($fieldTypeMeta, 'OutputField') + $this->typeMetaReader->read($fieldTypeMeta, TypeMetaWrapperReader::OUTPUT_FIELD_PARAMETER) ); - if ($this->docReader->readTypeDescription($fieldMeta->astNode->directives)) { - $result['description'] = $this->docReader->readTypeDescription($fieldMeta->astNode->directives); + if ($this->docReader->read($fieldMeta->astNode->directives)) { + $result['description'] = $this->docReader->read($fieldMeta->astNode->directives); } $arguments = $fieldMeta->args; @@ -65,22 +72,24 @@ public function readFieldMeta(\GraphQL\Type\Definition\FieldDefinition $fieldMet $typeMeta = $argumentMeta->getType(); $result['arguments'][$argumentName] = array_merge( $result['arguments'][$argumentName], - $this->typeMetaReader->readTypeMeta($typeMeta, 'Argument') + $this->typeMetaReader->read($typeMeta, TypeMetaWrapperReader::ARGUMENT_PARAMETER) ); - if ($this->docReader->readTypeDescription($argumentMeta->astNode->directives)) { + if ($this->docReader->read($argumentMeta->astNode->directives)) { $result['arguments'][$argumentName]['description'] = - $this->docReader->readTypeDescription($argumentMeta->astNode->directives); + $this->docReader->read($argumentMeta->astNode->directives); } } return $result; } /** + * Read resolver if an annotation with the class of the resolver is defined in the meta + * * @param \GraphQL\Type\Definition\FieldDefinition $fieldMeta * @return string|null */ - private function readFieldResolver(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) : ?string + private function getFieldResolver(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) : ?string { /** @var \GraphQL\Language\AST\NodeList $directives */ $directives = $fieldMeta->astNode->directives; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/ImplementsReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/ImplementsReader.php new file mode 100644 index 0000000000000..b7a149c2dd78c --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/ImplementsReader.php @@ -0,0 +1,42 @@ +name->value == 'implements') { + foreach ($directive->arguments as $directiveArgument) { + if ($directiveArgument->name->value == 'interfaces') { + if ($directiveArgument->value->kind == 'ListValue') { + $interfacesNames = []; + foreach ($directiveArgument->value->values as $stringValue) { + $interfacesNames[] = $stringValue->value; + } + return $interfacesNames; + } else { + return [$directiveArgument->value->value]; + } + } + } + } + } + return []; + } +} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaWrapperReader.php similarity index 71% rename from lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php rename to lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaWrapperReader.php index a42e781808991..fb25d4b90aca7 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaWrapperReader.php @@ -7,16 +7,23 @@ namespace Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader; -class TypeMetaReader +/** + * Common cases for types that need extra formatting like wrapping or additional properties added to their definition + */ +class TypeMetaWrapperReader { + const ARGUMENT_PARAMETER = 'Argument'; + const OUTPUT_FIELD_PARAMETER = 'OutputField'; + const INPUT_FIELD_PARAMETER = 'InputField'; + /** - * Read meta from type meta and parameter type + * Read from type meta data and determine wrapping types that are needed and extra properties that need to be added * - * @param $meta + * @param \GraphQL\Type\Definition\Type $meta * @param string $parameterType Argument|OutputField|InputField * @return array */ - public function readTypeMeta($meta, $parameterType = 'Argument') : array + public function read(\GraphQL\Type\Definition\Type $meta, string $parameterType) : array { $result = []; if ($meta instanceof \GraphQL\Type\Definition\NonNull) { diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php index 7141aad4998b2..c0a9a4d09c5d4 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php @@ -42,14 +42,14 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array '_value' => $enumValueMeta->value ]; - if ($this->docReader->readTypeDescription($enumValueMeta->astNode->directives)) { + if ($this->docReader->read($enumValueMeta->astNode->directives)) { $result['items'][$enumValueMeta->value]['description'] = - $this->docReader->readTypeDescription($enumValueMeta->astNode->directives); + $this->docReader->read($enumValueMeta->astNode->directives); } } - if ($this->docReader->readTypeDescription($typeMeta->astNode->directives)) { - $result['description'] = $this->docReader->readTypeDescription($typeMeta->astNode->directives); + if ($this->docReader->read($typeMeta->astNode->directives)) { + $result['description'] = $this->docReader->read($typeMeta->astNode->directives); } return $result; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php index 38f3010369c93..9ba5d9c4fa612 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php @@ -8,13 +8,13 @@ namespace Magento\Framework\GraphQl\Config\GraphQlReader\Reader; use Magento\Framework\GraphQl\Config\GraphQlReader\TypeMetaReaderInterface; -use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\TypeMetaReader; +use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\TypeMetaWrapperReader; use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\DocReader; class InputObjectType implements TypeMetaReaderInterface { /** - * @var TypeMetaReader + * @var TypeMetaWrapperReader */ private $typeMetaReader; @@ -24,10 +24,10 @@ class InputObjectType implements TypeMetaReaderInterface private $docReader; /** - * @param TypeMetaReader $typeMetaReader + * @param TypeMetaWrapperReader $typeMetaReader * @param DocReader $docReader */ - public function __construct(TypeMetaReader $typeMetaReader, DocReader $docReader) + public function __construct(TypeMetaWrapperReader $typeMetaReader, DocReader $docReader) { $this->typeMetaReader = $typeMetaReader; $this->docReader = $docReader; @@ -50,8 +50,8 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array $result['fields'][$fieldName] = $this->readInputObjectFieldMeta($fieldMeta); } - if ($this->docReader->readTypeDescription($typeMeta->astNode->directives)) { - $result['description'] = $this->docReader->readTypeDescription($typeMeta->astNode->directives); + if ($this->docReader->read($typeMeta->astNode->directives)) { + $result['description'] = $this->docReader->read($typeMeta->astNode->directives); } return $result; } else { @@ -73,10 +73,13 @@ private function readInputObjectFieldMeta(\GraphQL\Type\Definition\InputObjectFi 'arguments' => [] ]; - $result = array_merge($result, $this->typeMetaReader->readTypeMeta($typeMeta, 'InputField')); + $result = array_merge( + $result, + $this->typeMetaReader->read($typeMeta, TypeMetaWrapperReader::INPUT_FIELD_PARAMETER) + ); - if ($this->docReader->readTypeDescription($fieldMeta->astNode->directives)) { - $result['description'] = $this->docReader->readTypeDescription($fieldMeta->astNode->directives); + if ($this->docReader->read($fieldMeta->astNode->directives)) { + $result['description'] = $this->docReader->read($fieldMeta->astNode->directives); } return $result; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php index 00299a5463158..58349e956bf1e 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php @@ -54,11 +54,11 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array $fields = $typeMeta->getFields(); foreach ($fields as $fieldName => $fieldMeta) { - $result['fields'][$fieldName] = $this->fieldMetaReader->readFieldMeta($fieldMeta); + $result['fields'][$fieldName] = $this->fieldMetaReader->read($fieldMeta); } - if ($this->docReader->readTypeDescription($typeMeta->astNode->directives)) { - $result['description'] = $this->docReader->readTypeDescription($typeMeta->astNode->directives); + if ($this->docReader->read($typeMeta->astNode->directives)) { + $result['description'] = $this->docReader->read($typeMeta->astNode->directives); } return $result; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php index cf96f52b91a7e..dab207e51770f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php @@ -10,6 +10,7 @@ use Magento\Framework\GraphQl\Config\GraphQlReader\TypeMetaReaderInterface; use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\FieldMetaReader; use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\DocReader; +use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\ImplementsReader; class ObjectType implements TypeMetaReaderInterface { @@ -23,14 +24,24 @@ class ObjectType implements TypeMetaReaderInterface */ private $docReader; + /** + * @var ImplementsReader + */ + private $implementsAnnotation; + /** * @param FieldMetaReader $fieldMetaReader * @param DocReader $docReader + * @param ImplementsReader $implementsAnnotation */ - public function __construct(FieldMetaReader $fieldMetaReader, DocReader $docReader) - { + public function __construct( + FieldMetaReader $fieldMetaReader, + DocReader $docReader, + ImplementsReader $implementsAnnotation + ) { $this->fieldMetaReader = $fieldMetaReader; $this->docReader = $docReader; + $this->implementsAnnotation = $implementsAnnotation; } /** @@ -46,7 +57,7 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array 'fields' => [], // Populated later ]; - $interfacesNames = $this->readCopyFieldsAnnotation($typeMeta->astNode->directives); + $interfacesNames = $this->implementsAnnotation->read($typeMeta->astNode->directives); foreach ($interfacesNames as $interfaceName) { $result['implements'][$interfaceName] = [ 'interface' => $interfaceName, @@ -56,11 +67,11 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array $fields = $typeMeta->getFields(); foreach ($fields as $fieldName => $fieldMeta) { - $result['fields'][$fieldName] = $this->fieldMetaReader->readFieldMeta($fieldMeta); + $result['fields'][$fieldName] = $this->fieldMetaReader->read($fieldMeta); } - if ($this->docReader->readTypeDescription($typeMeta->astNode->directives)) { - $result['description'] = $this->docReader->readTypeDescription($typeMeta->astNode->directives); + if ($this->docReader->read($typeMeta->astNode->directives)) { + $result['description'] = $this->docReader->read($typeMeta->astNode->directives); } return $result; @@ -69,34 +80,6 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : ?array } } - /** - * Read copyFields annotation for a specific node if exists - * - * @param \GraphQL\Language\AST\NodeList $directives - * @return string[]|null - */ - public function readCopyFieldsAnnotation(\GraphQL\Language\AST\NodeList $directives) : array - { - foreach ($directives as $directive) { - if ($directive->name->value == 'implements') { - foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'interfaces') { - if ($directiveArgument->value->kind == 'ListValue') { - $interfacesNames = []; - foreach ($directiveArgument->value->values as $stringValue) { - $interfacesNames[] = $stringValue->value; - } - return $interfacesNames; - } else { - return [$directiveArgument->value->value]; - } - } - } - } - } - return []; - } - /** * Find interface graphql type in array list of strings * diff --git a/lib/internal/Magento/Framework/GraphQl/HttpHeaderProcessorInterface.php b/lib/internal/Magento/Framework/GraphQl/HttpHeaderProcessorInterface.php index 5f2399de6ed20..afc0304dd3a8f 100644 --- a/lib/internal/Magento/Framework/GraphQl/HttpHeaderProcessorInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/HttpHeaderProcessorInterface.php @@ -18,8 +18,8 @@ interface HttpHeaderProcessorInterface * This method should be called even if a header entry is not present on a request * to enforce required headers like "application/json" * - * @param bool|string $headerValue + * @param string $headerValue * @return void */ - public function processHeaderValue($headerValue) : void; + public function processHeaderValue(string $headerValue) : void; } diff --git a/lib/internal/Magento/Framework/GraphQl/HttpRequestProcessor.php b/lib/internal/Magento/Framework/GraphQl/HttpRequestProcessor.php index 1b36e2c8b5249..1771b11e41b5f 100644 --- a/lib/internal/Magento/Framework/GraphQl/HttpRequestProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/HttpRequestProcessor.php @@ -36,7 +36,7 @@ public function __construct(array $graphQlHeaders) public function processHeaders(Http $request) : void { foreach ($this->headerProcessors as $headerName => $headerClass) { - $headerClass->processHeaderValue($request->getHeader($headerName)); + $headerClass->processHeaderValue((string)$request->getHeader($headerName)); } } } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php index 328dd22cc6983..f7ccf83845793 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputMapper.php @@ -87,19 +87,19 @@ public function getRepresentation(Argument $argument) : array 'description' => $argument->getDescription() ]; - if ($this->scalarTypes->isScalarType($typeName) && $argument->getDefault() !== null) { + if ($this->scalarTypes->isScalarType($typeName) && $argument->getDefaultValue() !== null) { switch ($argument->getTypeName()) { case 'Int': - $calculatedArgument['defaultValue'] = (int)$argument->getDefault(); + $calculatedArgument['defaultValue'] = (int)$argument->getDefaultValue(); break; case 'Float': - $calculatedArgument['defaultValue'] = (float)$argument->getDefault(); + $calculatedArgument['defaultValue'] = (float)$argument->getDefaultValue(); break; case 'Boolean': - $calculatedArgument['defaultValue'] = (bool)$argument->getDefault(); + $calculatedArgument['defaultValue'] = (bool)$argument->getDefaultValue(); break; default: - $calculatedArgument['defaultValue'] = $argument->getDefault(); + $calculatedArgument['defaultValue'] = $argument->getDefaultValue(); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php index cbb4d74efb231..cd5f4846bedcf 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Interfaces.php @@ -11,7 +11,6 @@ use Magento\Framework\GraphQl\Config\Data\TypeInterface; use Magento\Framework\GraphQl\Config\Data\Type; use Magento\Framework\GraphQl\Type\Output\ElementMapper\FormatterInterface; -use Magento\Framework\ObjectManagerInterface; use Magento\Framework\GraphQl\Type\Output\OutputMapper; /** @@ -19,22 +18,16 @@ */ class Interfaces implements FormatterInterface { - /** - * @var ObjectManagerInterface - */ - private $objectManager; - /** * @var OutputMapper */ private $outputMapper; /** - * @param ObjectManagerInterface $objectManager + * @param OutputMapper $outputMapper */ - public function __construct(ObjectManagerInterface $objectManager, OutputMapper $outputMapper) + public function __construct(OutputMapper $outputMapper) { - $this->objectManager = $objectManager; $this->outputMapper = $outputMapper; } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/SchemaFactory.php b/lib/internal/Magento/Framework/GraphQl/Type/SchemaFactory.php index c03b5a4604380..3462f30ea6370 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/SchemaFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/SchemaFactory.php @@ -18,7 +18,7 @@ class SchemaFactory * @param array $config * @return Schema */ - public function create($config) : Schema + public function create(array $config) : Schema { return new Schema($config); } From 3abd6212d0f31286eb0fc06075c2b8c96c131618 Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Mon, 26 Mar 2018 15:19:44 -0500 Subject: [PATCH 237/668] MAGETWO-89366: Create integration or api tests - integration test for SDL with empty types and description --- .../GraphQl/Config/GraphQlReaderTest.php | 19 +- .../Framework/GraphQl/_files/schemaA.graphql | 4 +- .../Framework/GraphQl/_files/schemaB.graphql | 147 +- .../_files/schema_with_description_sdl.php | 4674 +++++++---------- 4 files changed, 1929 insertions(+), 2915 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php index 8217a8ded979b..01d7da0eb39dd 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php @@ -16,7 +16,7 @@ /** * Tests the entire process of generating a schema from a given SDL and processing a request/query * - * @package Magento\Framework\GraphQl\Config + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @magentoAppArea graphql */ class GraphQlReaderTest extends \PHPUnit\Framework\TestCase @@ -194,5 +194,22 @@ enumValues(includeDeprecated: true) { 'Missing type in the response' ); } + //Checks to make sure that the the given description exists in the expectedOutput array + $this->assertTrue(array_key_exists( + array_search( + 'Comment for empty PhysicalProductInterface', + array_column($expectedOutput, 'description') + ), + $expectedOutput + ) + ); + $this->assertTrue(array_key_exists( + array_search( + 'Comment for empty Enum', + array_column($expectedOutput, 'description') + ), + $expectedOutput + ) + ); } } diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphql b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphql index 395cd46aee764..d736bb4fa26f1 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphql +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphql @@ -34,12 +34,12 @@ enum SortEnum @doc(description: "Comment for SortEnum.") } interface ProductInterface { - url_key: String @doc(description: "comment for url_key inside [ProductInterface].") + url_key: String @doc(description: "comment for url_key inside ProductInterface type.") url_path: String } type SimpleProduct { - url_key: String @doc(description: "comment for url_key for simple Product which implements ProductInterface") + url_key: String @doc(description: "comment for url_key for simple product that implements [ProductInterface]") url_path: String } diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaB.graphql b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaB.graphql index a8d317a8719dc..08241135a8608 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaB.graphql +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaB.graphql @@ -92,33 +92,11 @@ interface ProductInterface id: Int @doc(description: "comment for [ProductInterface].") name: String sku: String - description: String - short_description: String special_price: Float special_from_date: String - special_to_date: String attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String updated_at: String country_of_manufacture: String type_id: String @@ -128,19 +106,18 @@ interface ProductInterface media_gallery_entries: [MediaGalleryEntry] tier_prices: [ProductTierPrices] price: ProductPrices - gift_message_available: String manufacturer: Int } -interface PhysicalProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") { - weight: Float +interface PhysicalProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") @doc(description:"Comment for empty PhysicalProductInterface") { + } type CustomizableAreaOption implements CustomizableOptionInterface { value: CustomizableAreaValue product_sku: String - title: String @doc(description:"Comment for CustomizableAreaOption that implements CustomizableOptionInterface") + title: String @doc(description:"Comment for title field for CustomizableAreaOption concrete type") required: Boolean sort_order: Int } @@ -155,7 +132,7 @@ type CustomizableAreaValue { type CustomizableDateOption implements CustomizableOptionInterface { value: CustomizableDateValue product_sku: String - title: String + title: String @doc(description:"This description should override interface comment.") required: Boolean sort_order: Int } @@ -168,9 +145,7 @@ type CustomizableDateValue { type CustomizableDropDownOption implements CustomizableOptionInterface { value: [CustomizableDropDownValue] - title: String - required: Boolean - sort_order: Int + required: Boolean @doc(description:"Comment for required field for CustomizableDropDownOption concrete type") } type CustomizableDropDownValue { @@ -185,9 +160,7 @@ type CustomizableDropDownValue { type CustomizableFieldOption implements CustomizableOptionInterface { value: CustomizableFieldValue product_sku: String - title: String - required: Boolean - sort_order: Int + sort_order: Int @doc(description:"Comment for sort_order for CustomizableFieldOption concrete type") } type CustomizableFieldValue { @@ -200,9 +173,6 @@ type CustomizableFieldValue { type CustomizableFileOption implements CustomizableOptionInterface { value: CustomizableFileValue product_sku: String - title: String - required: Boolean - sort_order: Int } type CustomizableFileValue { @@ -226,9 +196,6 @@ interface CustomizableProductInterface @typeResolver(class: "Magento\\CatalogGra type CustomizableRadioOption implements CustomizableOptionInterface { value: [CustomizableRadioValue] - title: String - required: Boolean - sort_order: Int } type CustomizableRadioValue { @@ -241,95 +208,11 @@ type CustomizableRadioValue { } type VirtualProduct implements ProductInterface, CustomizableProductInterface { - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - options: [CustomizableOptionInterface] - manufacturer: Int } type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface -@doc(description: "comment for items[ProductInterface].") { - id: Int - name: String - sku: String - description: String - short_description: String - special_price: Float - special_from_date: String - special_to_date: String - attribute_set_id: Int - meta_title: String - meta_keyword: String - meta_description: String - image: String - small_image: String - thumbnail: String - new_from_date: String - new_to_date: String - tier_price: Float - custom_design: String - custom_design_from: String - custom_design_to: String - custom_layout_update: String - custom_layout: String - page_layout: String - category_ids: [Int] - options_container: String - image_label: String - small_image_label: String - thumbnail_label: String - created_at: String - updated_at: String - country_of_manufacture: String - type_id: String - website_ids: [Int] - category_links: [ProductCategoryLinks] - product_links: [ProductLinksInterface] - media_gallery_entries: [MediaGalleryEntry] - tier_prices: [ProductTierPrices] - price: ProductPrices - gift_message_available: String - weight: Float - options: [CustomizableOptionInterface] - manufacturer: Int +@doc(description: "Comment for empty SimpleProduct type") +{ } type Products @doc(description:"Comment for Products") { @@ -433,7 +316,7 @@ input ProductSortInput @doc(description:"Input ProductSortInput") { } type MediaGalleryEntry -@doc(description: "comment for MediaGalleryEntry") +@doc(description: "Comment for MediaGalleryEntry type") { id: Int @doc(description: "id for MediaGalleryEntry") media_type: String @@ -445,3 +328,15 @@ type MediaGalleryEntry content: ProductMediaGalleryEntriesContent @doc(description: "Comment for ProductMediaGalleryEntriesContent on content field") video_content: ProductMediaGalleryEntriesVideoContent } + +type EntityUrl { + id: Int + canonical_url: String + type: UrlRewriteEntityTypeEnum +} +enum UrlRewriteEntityTypeEnum @doc(description: "Comment for empty Enum") +{ + +} + + diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_with_description_sdl.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_with_description_sdl.php index 8a9af4da9b9e3..75b9a824a2277 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_with_description_sdl.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_with_description_sdl.php @@ -1123,222 +1123,364 @@ 'possibleTypes' => null ], [ - 'kind' => 'INTERFACE', - 'name' => 'ProductInterface', - 'description' => 'comment for ProductInterface', - 'fields' => [ + 'kind'=> 'INTERFACE', + 'name'=> 'ProductInterface', + 'description'=> 'comment for ProductInterface', + 'fields'=> [ [ - 'name' => 'url_key', - 'description' => 'comment for url_key inside [ProductInterface].', - 'args' => [ + 'name'=> 'url_key', + 'description'=> 'comment for url_key inside ProductInterface type.', + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'url_path', - 'description' => null, - 'args' => [ + 'name'=> 'url_path', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'id', - 'description' => 'comment for [ProductInterface].', - 'args' => [ + 'name'=> 'id', + 'description'=> 'comment for [ProductInterface].', + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'name', - 'description' => null, - 'args' => [ + 'name'=> 'name', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'sku', - 'description' => null, - 'args' => [ + 'name'=> 'sku', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'description', - 'description' => null, - 'args' => [ + 'name'=> 'special_price', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Float', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'short_description', - 'description' => null, - 'args' => [ + 'name'=> 'special_from_date', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'special_price', - 'description' => null, - 'args' => [ + 'name'=> 'attribute_set_id', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'special_from_date', - 'description' => null, - 'args' => [ + 'name'=> 'tier_price', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Float', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'special_to_date', - 'description' => null, - 'args' => [ + 'name'=> 'category_ids', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null + ] ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'attribute_set_id', - 'description' => null, - 'args' => [ + 'name'=> 'updated_at', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'meta_title', - 'description' => null, - 'args' => [ + 'name'=> 'country_of_manufacture', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'meta_keyword', - 'description' => null, - 'args' => [ + 'name'=> 'type_id', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'meta_description', - 'description' => null, - 'args' => [ + 'name'=> 'website_ids', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null + ] ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'image', + 'name'=> 'category_links', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'ProductCategoryLinks', + 'ofType'=> null + ] + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], + [ + 'name'=> 'product_links', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'INTERFACE', + 'name'=> 'ProductLinksInterface', + 'ofType'=> null + ] + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], + [ + 'name'=> 'media_gallery_entries', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'MediaGalleryEntry', + 'ofType'=> null + ] + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], + [ + 'name'=> 'tier_prices', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'ProductTierPrices', + 'ofType'=> null + ] + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], + [ + 'name'=> 'price', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'ProductPrices', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], + [ + 'name'=> 'manufacturer', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ] + ], + 'inputFields'=> null, + 'interfaces'=> null, + 'enumValues'=> null, + 'possibleTypes'=> [ + [ + 'kind'=> 'OBJECT', + 'name'=> 'SimpleProduct', + 'ofType'=> null + ], + [ + 'kind'=> 'OBJECT', + 'name'=> 'VirtualProduct', + 'ofType'=> null + ] + ] + ], + [ + 'kind' => 'SCALAR', + 'name' => 'Float', + 'description' => 'The `Float` scalar type represents signed double-precision fractional' . "\n" . + 'values as specified by' . "\n" . + '[IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point). ', + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'ProductCategoryLinks', + 'description' => '', + 'fields' => [ + [ + 'name' => 'position', 'description' => null, 'args' => [ ], 'type' => [ 'kind' => 'SCALAR', - 'name' => 'String', + 'name' => 'Int', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'small_image', + 'name' => 'category_id', 'description' => null, 'args' => [ @@ -1350,9 +1492,22 @@ ], 'isDeprecated' => false, 'deprecationReason' => null - ], + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'INTERFACE', + 'name' => 'ProductLinksInterface', + 'description' => '', + 'fields' => [ [ - 'name' => 'thumbnail', + 'name' => 'sku', 'description' => null, 'args' => [ @@ -1366,7 +1521,7 @@ 'deprecationReason' => null ], [ - 'name' => 'new_from_date', + 'name' => 'link_type', 'description' => null, 'args' => [ @@ -1380,7 +1535,7 @@ 'deprecationReason' => null ], [ - 'name' => 'new_to_date', + 'name' => 'linked_product_sku', 'description' => null, 'args' => [ @@ -1394,49 +1549,66 @@ 'deprecationReason' => null ], [ - 'name' => 'tier_price', + 'name' => 'linked_product_type', 'description' => null, 'args' => [ ], 'type' => [ 'kind' => 'SCALAR', - 'name' => 'Float', + 'name' => 'String', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'custom_design', + 'name' => 'position', 'description' => null, 'args' => [ ], 'type' => [ 'kind' => 'SCALAR', - 'name' => 'String', + 'name' => 'Int', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null - ], + ] + ], + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => [ [ - 'name' => 'custom_design_from', - 'description' => null, + 'kind' => 'OBJECT', + 'name' => 'ProductLinks', + 'ofType' => null + ] + ] + ], + [ + 'kind' => 'OBJECT', + 'name' => 'MediaGalleryEntry', + 'description' => 'Comment for MediaGalleryEntry type', + 'fields' => [ + [ + 'name' => 'id', + 'description' => 'id for MediaGalleryEntry', 'args' => [ ], 'type' => [ 'kind' => 'SCALAR', - 'name' => 'String', + 'name' => 'Int', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'custom_design_to', + 'name' => 'media_type', 'description' => null, 'args' => [ @@ -1450,7 +1622,7 @@ 'deprecationReason' => null ], [ - 'name' => 'custom_layout_update', + 'name' => 'label', 'description' => null, 'args' => [ @@ -1464,35 +1636,35 @@ 'deprecationReason' => null ], [ - 'name' => 'custom_layout', + 'name' => 'position', 'description' => null, 'args' => [ ], 'type' => [ 'kind' => 'SCALAR', - 'name' => 'String', + 'name' => 'Int', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'page_layout', + 'name' => 'disabled', 'description' => null, 'args' => [ ], 'type' => [ 'kind' => 'SCALAR', - 'name' => 'String', + 'name' => 'Boolean', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'category_ids', + 'name' => 'types', 'description' => null, 'args' => [ @@ -1502,7 +1674,7 @@ 'name' => null, 'ofType' => [ 'kind' => 'SCALAR', - 'name' => 'Int', + 'name' => 'String', 'ofType' => null ] ], @@ -1510,7 +1682,7 @@ 'deprecationReason' => null ], [ - 'name' => 'options_container', + 'name' => 'file', 'description' => null, 'args' => [ @@ -1524,21 +1696,58 @@ 'deprecationReason' => null ], [ - 'name' => 'image_label', - 'description' => null, + 'name' => 'content', + 'description' => 'Comment for ProductMediaGalleryEntriesContent on content field', 'args' => [ ], 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', + 'kind' => 'OBJECT', + 'name' => 'ProductMediaGalleryEntriesContent', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'small_image_label', + 'name' => 'video_content', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'ProductMediaGalleryEntriesVideoContent', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'SCALAR', + 'name' => 'Boolean', + 'description' => 'The `Boolean` scalar type represents `true` or `false`.', + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'ProductMediaGalleryEntriesContent', + 'description' => 'Comment for ProductMediaGalleryEntriesContent.', + 'fields' => [ + [ + 'name' => 'base64_encoded_data', 'description' => null, 'args' => [ @@ -1552,7 +1761,7 @@ 'deprecationReason' => null ], [ - 'name' => 'thumbnail_label', + 'name' => 'type', 'description' => null, 'args' => [ @@ -1566,7 +1775,7 @@ 'deprecationReason' => null ], [ - 'name' => 'created_at', + 'name' => 'name', 'description' => null, 'args' => [ @@ -1578,9 +1787,22 @@ ], 'isDeprecated' => false, 'deprecationReason' => null - ], + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'ProductMediaGalleryEntriesVideoContent', + 'description' => '', + 'fields' => [ [ - 'name' => 'updated_at', + 'name' => 'media_type', 'description' => null, 'args' => [ @@ -1594,7 +1816,7 @@ 'deprecationReason' => null ], [ - 'name' => 'country_of_manufacture', + 'name' => 'video_provider', 'description' => null, 'args' => [ @@ -1608,7 +1830,7 @@ 'deprecationReason' => null ], [ - 'name' => 'type_id', + 'name' => 'video_url', 'description' => null, 'args' => [ @@ -1622,132 +1844,125 @@ 'deprecationReason' => null ], [ - 'name' => 'website_ids', + 'name' => 'video_title', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ] + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'category_links', + 'name' => 'video_description', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'OBJECT', - 'name' => 'ProductCategoryLinks', - 'ofType' => null - ] + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'product_links', + 'name' => 'video_metadata', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'INTERFACE', - 'name' => 'ProductLinksInterface', - 'ofType' => null - ] + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null - ], + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'ProductTierPrices', + 'description' => '', + 'fields' => [ [ - 'name' => 'media_gallery_entries', + 'name' => 'customer_group_id', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'OBJECT', - 'name' => 'MediaGalleryEntry', - 'ofType' => null - ] + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'tier_prices', + 'name' => 'qty', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'OBJECT', - 'name' => 'ProductTierPrices', - 'ofType' => null - ] + 'kind' => 'SCALAR', + 'name' => 'Float', + 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'price', + 'name' => 'value', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'OBJECT', - 'name' => 'ProductPrices', + 'kind' => 'SCALAR', + 'name' => 'Float', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'gift_message_available', + 'name' => 'percentage_value', 'description' => null, 'args' => [ ], 'type' => [ 'kind' => 'SCALAR', - 'name' => 'String', + 'name' => 'Float', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'manufacturer', + 'name' => 'website_id', 'description' => null, 'args' => [ ], 'type' => [ 'kind' => 'SCALAR', - 'name' => 'Int', + 'name' => 'Float', 'ofType' => null ], 'isDeprecated' => false, @@ -1755,61 +1970,54 @@ ] ], 'inputFields' => null, - 'interfaces' => null, - 'enumValues' => null, - 'possibleTypes' => [ - [ - 'kind' => 'OBJECT', - 'name' => 'SimpleProduct', - 'ofType' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'VirtualProduct', - 'ofType' => null - ] - ] - ], - [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'description' => 'The `Float` scalar type represents signed double-precision fractional' . "\n" . - 'values as specified by' . "\n" . - '[IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point). ', - 'fields' => null, - 'inputFields' => null, - 'interfaces' => null, + 'interfaces' => [ + + ], 'enumValues' => null, 'possibleTypes' => null ], [ 'kind' => 'OBJECT', - 'name' => 'ProductCategoryLinks', + 'name' => 'ProductPrices', 'description' => '', 'fields' => [ [ - 'name' => 'position', + 'name' => 'minimalPrice', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', + 'kind' => 'OBJECT', + 'name' => 'Price', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'category_id', + 'name' => 'maximalPrice', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', + 'kind' => 'OBJECT', + 'name' => 'Price', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null + ], + [ + 'name' => 'regularPrice', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'OBJECT', + 'name' => 'Price', 'ofType' => null ], 'isDeprecated' => false, @@ -1824,222 +2032,78 @@ 'possibleTypes' => null ], [ - 'kind' => 'INTERFACE', - 'name' => 'ProductLinksInterface', + 'kind' => 'OBJECT', + 'name' => 'Price', 'description' => '', 'fields' => [ [ - 'name' => 'sku', + 'name' => 'amount', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', + 'kind' => 'OBJECT', + 'name' => 'Money', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'link_type', + 'name' => 'adjustments', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'kind' => 'LIST', + 'name' => null, + 'ofType' => [ + 'kind' => 'OBJECT', + 'name' => 'PriceAdjustment', + 'ofType' => null + ] ], 'isDeprecated' => false, 'deprecationReason' => null - ], + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'Money', + 'description' => '', + 'fields' => [ [ - 'name' => 'linked_product_sku', + 'name' => 'value', 'description' => null, 'args' => [ ], 'type' => [ 'kind' => 'SCALAR', - 'name' => 'String', + 'name' => 'Float', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'linked_product_type', + 'name' => 'currency', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'position', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => null, - 'enumValues' => null, - 'possibleTypes' => [ - [ - 'kind' => 'OBJECT', - 'name' => 'ProductLinks', - 'ofType' => null - ] - ] - ], - [ - 'kind' => 'OBJECT', - 'name' => 'MediaGalleryEntry', - 'description' => 'comment for MediaGalleryEntry', - 'fields' => [ - [ - 'name' => 'id', - 'description' => 'id for MediaGalleryEntry', - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'media_type', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'label', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'position', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'disabled', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Boolean', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'types', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ] - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'file', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'content', - 'description' => 'Comment for ProductMediaGalleryEntriesContent on content field', - 'args' => [ - - ], - 'type' => [ - 'kind' => 'OBJECT', - 'name' => 'ProductMediaGalleryEntriesContent', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'video_content', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'OBJECT', - 'name' => 'ProductMediaGalleryEntriesVideoContent', + 'kind' => 'ENUM', + 'name' => 'CurrencyEnum', 'ofType' => null ], 'isDeprecated' => false, @@ -2054,1464 +2118,155 @@ 'possibleTypes' => null ], [ - 'kind' => 'SCALAR', - 'name' => 'Boolean', - 'description' => 'The `Boolean` scalar type represents `true` or `false`.', + 'kind' => 'ENUM', + 'name' => 'CurrencyEnum', + 'description' => '', 'fields' => null, 'inputFields' => null, 'interfaces' => null, - 'enumValues' => null, - 'possibleTypes' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'ProductMediaGalleryEntriesContent', - 'description' => 'Comment for ProductMediaGalleryEntriesContent.', - 'fields' => [ - [ - 'name' => 'base64_encoded_data', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'type', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'name', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ - - ], - 'enumValues' => null, - 'possibleTypes' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'ProductMediaGalleryEntriesVideoContent', - 'description' => '', - 'fields' => [ + 'enumValues' => [ [ - 'name' => 'media_type', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'name' => 'AFN', + 'description' => '', + 'isDeprecated' => false ], [ - 'name' => 'video_provider', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'name' => 'GBP', + 'description' => '', + 'isDeprecated' => false ], - [ - 'name' => 'video_url', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'video_title', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'video_description', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'video_metadata', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ - - ], - 'enumValues' => null, - 'possibleTypes' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'ProductTierPrices', - 'description' => '', - 'fields' => [ - [ - 'name' => 'customer_group_id', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'qty', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'value', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'percentage_value', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'website_id', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ - - ], - 'enumValues' => null, - 'possibleTypes' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'ProductPrices', - 'description' => '', - 'fields' => [ - [ - 'name' => 'minimalPrice', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'OBJECT', - 'name' => 'Price', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'maximalPrice', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'OBJECT', - 'name' => 'Price', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'regularPrice', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'OBJECT', - 'name' => 'Price', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ - - ], - 'enumValues' => null, - 'possibleTypes' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'Price', - 'description' => '', - 'fields' => [ - [ - 'name' => 'amount', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'OBJECT', - 'name' => 'Money', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'adjustments', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'OBJECT', - 'name' => 'PriceAdjustment', - 'ofType' => null - ] - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ - - ], - 'enumValues' => null, - 'possibleTypes' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'Money', - 'description' => '', - 'fields' => [ - [ - 'name' => 'value', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'currency', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'ENUM', - 'name' => 'CurrencyEnum', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ - - ], - 'enumValues' => null, - 'possibleTypes' => null - ], - [ - 'kind' => 'ENUM', - 'name' => 'CurrencyEnum', - 'description' => '', - 'fields' => null, - 'inputFields' => null, - 'interfaces' => null, - 'enumValues' => [ - [ - 'name' => 'AFN', - 'description' => '', - 'isDeprecated' => false - ], - [ - 'name' => 'GBP', - 'description' => '', - 'isDeprecated' => false - ], - [ - 'name' => 'EUR', - 'description' => '', - 'isDeprecated' => false - ], - [ - 'name' => 'INR', - 'description' => '', - 'isDeprecated' => false - ], - [ - 'name' => 'USD', - 'description' => '', - 'isDeprecated' => false - ] - ], - 'possibleTypes' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'PriceAdjustment', - 'description' => '', - 'fields' => [ - [ - 'name' => 'amount', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'OBJECT', - 'name' => 'Money', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'code', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'ENUM', - 'name' => 'PriceAdjustmentCodesEnum', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'description', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'ENUM', - 'name' => 'PriceAdjustmentDescriptionEnum', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ - - ], - 'enumValues' => null, - 'possibleTypes' => null - ], - [ - 'kind' => 'ENUM', - 'name' => 'PriceAdjustmentCodesEnum', - 'description' => '', - 'fields' => null, - 'inputFields' => null, - 'interfaces' => null, - 'enumValues' => [ - [ - 'name' => 'TAX', - 'description' => '', - 'isDeprecated' => false - ] - ], - 'possibleTypes' => null - ], - [ - 'kind' => 'ENUM', - 'name' => 'PriceAdjustmentDescriptionEnum', - 'description' => '', - 'fields' => null, - 'inputFields' => null, - 'interfaces' => null, - 'enumValues' => [ - [ - 'name' => 'INCLUDED', - 'description' => '', - 'isDeprecated' => false - ], - [ - 'name' => 'EXCLUDED', - 'description' => '', - 'isDeprecated' => false - ] - ], - 'possibleTypes' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'SearchResultPageInfo', - 'description' => 'Comment for SearchResultPageInfo', - 'fields' => [ - [ - 'name' => 'page_size', - 'description' => 'Comment for page_size', - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'current_page', - 'description' => 'Comment for current_page', - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ - - ], - 'enumValues' => null, - 'possibleTypes' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'SimpleProduct', - 'description' => 'comment for items[ProductInterface].', - 'fields' => [ - [ - 'name' => 'url_key', - 'description' => 'comment for url_key for simple Product which implements ProductInterface', - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'url_path', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'id', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'name', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'sku', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'description', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'short_description', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'special_price', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'special_from_date', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'special_to_date', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'attribute_set_id', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'meta_title', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'meta_keyword', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'meta_description', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'image', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'small_image', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'thumbnail', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'new_from_date', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'new_to_date', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'tier_price', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'custom_design', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'custom_design_from', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'custom_design_to', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'custom_layout_update', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'custom_layout', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'page_layout', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'category_ids', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ] - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'options_container', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'image_label', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'small_image_label', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'thumbnail_label', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'created_at', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'updated_at', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'country_of_manufacture', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'type_id', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'website_ids', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ] - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'category_links', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'OBJECT', - 'name' => 'ProductCategoryLinks', - 'ofType' => null - ] - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'product_links', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'INTERFACE', - 'name' => 'ProductLinksInterface', - 'ofType' => null - ] - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'media_gallery_entries', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'OBJECT', - 'name' => 'MediaGalleryEntry', - 'ofType' => null - ] - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'tier_prices', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'OBJECT', - 'name' => 'ProductTierPrices', - 'ofType' => null - ] - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'price', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'OBJECT', - 'name' => 'ProductPrices', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'gift_message_available', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'weight', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'options', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'INTERFACE', - 'name' => 'CustomizableOptionInterface', - 'ofType' => null - ] - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'manufacturer', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ - [ - 'kind' => 'INTERFACE', - 'name' => 'ProductInterface', - 'ofType' => null - ], - [ - 'kind' => 'INTERFACE', - 'name' => 'PhysicalProductInterface', - 'ofType' => null - ], - [ - 'kind' => 'INTERFACE', - 'name' => 'CustomizableProductInterface', - 'ofType' => null - ] - ], - 'enumValues' => null, - 'possibleTypes' => null - ], - [ - 'kind' => 'INTERFACE', - 'name' => 'PhysicalProductInterface', - 'description' => '', - 'fields' => [ - [ - 'name' => 'weight', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => null, - 'enumValues' => null, - 'possibleTypes' => [ - [ - 'kind' => 'OBJECT', - 'name' => 'SimpleProduct', - 'ofType' => null - ] - ] - ], - [ - 'kind' => 'INTERFACE', - 'name' => 'CustomizableProductInterface', - 'description' => '', - 'fields' => [ - [ - 'name' => 'options', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'INTERFACE', - 'name' => 'CustomizableOptionInterface', - 'ofType' => null - ] - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => null, - 'enumValues' => null, - 'possibleTypes' => [ - [ - 'kind' => 'OBJECT', - 'name' => 'SimpleProduct', - 'ofType' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'VirtualProduct', - 'ofType' => null - ] - ] - ], - [ - 'kind' => 'INTERFACE', - 'name' => 'CustomizableOptionInterface', - 'description' => '', - 'fields' => [ - [ - 'name' => 'title', - 'description' => 'Comment for CustomizableOptionInterface', - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'required', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Boolean', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], - [ - 'name' => 'sort_order', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => null, - 'enumValues' => null, - 'possibleTypes' => [ - [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableAreaOption', - 'ofType' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableDateOption', - 'ofType' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableDropDownOption', - 'ofType' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableFieldOption', - 'ofType' => null + [ + 'name' => 'EUR', + 'description' => '', + 'isDeprecated' => false ], [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableFileOption', - 'ofType' => null + 'name' => 'INR', + 'description' => '', + 'isDeprecated' => false ], [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableRadioOption', - 'ofType' => null + 'name' => 'USD', + 'description' => '', + 'isDeprecated' => false ] - ] + ], + 'possibleTypes' => null ], [ 'kind' => 'OBJECT', - 'name' => 'ProductLinks', + 'name' => 'PriceAdjustment', 'description' => '', 'fields' => [ [ - 'name' => 'sku', + 'name' => 'amount', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', + 'kind' => 'OBJECT', + 'name' => 'Money', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'link_type', + 'name' => 'code', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', + 'kind' => 'ENUM', + 'name' => 'PriceAdjustmentCodesEnum', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'linked_product_sku', + 'name' => 'description', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', + 'kind' => 'ENUM', + 'name' => 'PriceAdjustmentDescriptionEnum', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'ENUM', + 'name' => 'PriceAdjustmentCodesEnum', + 'description' => '', + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => [ + [ + 'name' => 'TAX', + 'description' => '', + 'isDeprecated' => false + ] + ], + 'possibleTypes' => null + ], + [ + 'kind' => 'ENUM', + 'name' => 'PriceAdjustmentDescriptionEnum', + 'description' => '', + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => [ + [ + 'name' => 'INCLUDED', + 'description' => '', + 'isDeprecated' => false ], [ - 'name' => 'linked_product_type', - 'description' => null, + 'name' => 'EXCLUDED', + 'description' => '', + 'isDeprecated' => false + ] + ], + 'possibleTypes' => null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'SearchResultPageInfo', + 'description' => 'Comment for SearchResultPageInfo', + 'fields' => [ + [ + 'name' => 'page_size', + 'description' => 'Comment for page_size', 'args' => [ ], 'type' => [ 'kind' => 'SCALAR', - 'name' => 'String', + 'name' => 'Int', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'position', - 'description' => null, + 'name' => 'current_page', + 'description' => 'Comment for current_page', 'args' => [ ], @@ -3526,346 +2281,385 @@ ], 'inputFields' => null, 'interfaces' => [ - [ - 'kind' => 'INTERFACE', - 'name' => 'ProductLinksInterface', - 'ofType' => null - ] + ], 'enumValues' => null, 'possibleTypes' => null ], [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableAreaOption', - 'description' => '', - 'fields' => [ + 'kind'=> 'OBJECT', + 'name'=> 'SimpleProduct', + 'description'=> 'Comment for empty SimpleProduct type', + 'fields'=> [ + [ + 'name'=> 'options', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'INTERFACE', + 'name'=> 'CustomizableOptionInterface', + 'ofType'=> null + ] + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], [ - 'name' => 'value', - 'description' => null, - 'args' => [ + 'name'=> 'url_key', + 'description'=> 'comment for url_key for simple product that implements [ProductInterface]', + 'args'=> [ ], - 'type' => [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableAreaValue', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'product_sku', - 'description' => null, - 'args' => [ + 'name'=> 'url_path', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'title', - 'description' => 'Comment for CustomizableAreaOption that implements CustomizableOptionInterface', - 'args' => [ + 'name'=> 'id', + 'description'=> 'comment for [ProductInterface].', + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'required', - 'description' => null, - 'args' => [ + 'name'=> 'name', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Boolean', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'sort_order', - 'description' => null, - 'args' => [ + 'name'=> 'sku', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ - [ - 'kind' => 'INTERFACE', - 'name' => 'CustomizableOptionInterface', - 'ofType' => null - ] - ], - 'enumValues' => null, - 'possibleTypes' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableAreaValue', - 'description' => '', - 'fields' => [ + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], [ - 'name' => 'price', - 'description' => null, - 'args' => [ + 'name'=> 'special_price', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Float', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'price_type', - 'description' => null, - 'args' => [ + 'name'=> 'special_from_date', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'ENUM', - 'name' => 'PriceTypeEnum', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'sku', - 'description' => null, - 'args' => [ + 'name'=> 'attribute_set_id', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'max_characters', - 'description' => null, - 'args' => [ + 'name'=> 'tier_price', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Float', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ - - ], - 'enumValues' => null, - 'possibleTypes' => null - ], - [ - 'kind' => 'ENUM', - 'name' => 'PriceTypeEnum', - 'description' => '', - 'fields' => null, - 'inputFields' => null, - 'interfaces' => null, - 'enumValues' => [ + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], [ - 'name' => 'FIXED', - 'description' => '', - 'isDeprecated' => false + 'name'=> 'category_ids', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null + ] + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'PERCENT', - 'description' => '', - 'isDeprecated' => false + 'name'=> 'updated_at', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'DYNAMIC', - 'description' => '', - 'isDeprecated' => false - ] - ], - 'possibleTypes' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableDateOption', - 'description' => '', - 'fields' => [ + 'name'=> 'country_of_manufacture', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], [ - 'name' => 'value', - 'description' => null, - 'args' => [ + 'name'=> 'type_id', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableDateValue', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'product_sku', - 'description' => null, - 'args' => [ + 'name'=> 'website_ids', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null + ] ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'title', - 'description' => null, - 'args' => [ + 'name'=> 'category_links', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'ProductCategoryLinks', + 'ofType'=> null + ] ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'required', - 'description' => null, - 'args' => [ + 'name'=> 'product_links', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Boolean', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'INTERFACE', + 'name'=> 'ProductLinksInterface', + 'ofType'=> null + ] ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'sort_order', - 'description' => null, - 'args' => [ + 'name'=> 'media_gallery_entries', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'MediaGalleryEntry', + 'ofType'=> null + ] ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ - [ - 'kind' => 'INTERFACE', - 'name' => 'CustomizableOptionInterface', - 'ofType' => null - ] - ], - 'enumValues' => null, - 'possibleTypes' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableDateValue', - 'description' => '', - 'fields' => [ + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], [ - 'name' => 'price', - 'description' => null, - 'args' => [ + 'name'=> 'tier_prices', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'ProductTierPrices', + 'ofType'=> null + ] ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'price_type', - 'description' => null, - 'args' => [ + 'name'=> 'price', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'ENUM', - 'name' => 'PriceTypeEnum', - 'ofType' => null + 'type'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'ProductPrices', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'sku', - 'description' => null, - 'args' => [ + 'name'=> 'manufacturer', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ] ], - 'inputFields' => null, - 'interfaces' => [ + 'inputFields'=> null, + 'interfaces'=> [ + [ + 'kind'=> 'INTERFACE', + 'name'=> 'ProductInterface', + 'ofType'=> null + ], + [ + 'kind'=> 'INTERFACE', + 'name'=> 'PhysicalProductInterface', + 'ofType'=> null + ], + [ + 'kind'=> 'INTERFACE', + 'name'=> 'CustomizableProductInterface', + 'ofType'=> null + ] + ], + 'enumValues'=> null, + 'possibleTypes'=> null + ], + [ + 'kind' => 'INTERFACE', + 'name' => 'PhysicalProductInterface', + 'description' => 'Comment for empty PhysicalProductInterface', + 'fields' => [ ], + 'inputFields' => null, + 'interfaces' => null, 'enumValues' => null, - 'possibleTypes' => null + 'possibleTypes' => [ + [ + 'kind' => 'OBJECT', + 'name' => 'SimpleProduct', + 'ofType' => null + ] + ] ], [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableDropDownOption', + 'kind' => 'INTERFACE', + 'name' => 'CustomizableProductInterface', 'description' => '', 'fields' => [ [ - 'name' => 'value', + 'name' => 'options', 'description' => null, 'args' => [ @@ -3874,17 +2668,39 @@ 'kind' => 'LIST', 'name' => null, 'ofType' => [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableDropDownValue', + 'kind' => 'INTERFACE', + 'name' => 'CustomizableOptionInterface', 'ofType' => null ] ], 'isDeprecated' => false, 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => null, + 'possibleTypes' => [ + [ + 'kind' => 'OBJECT', + 'name' => 'SimpleProduct', + 'ofType' => null ], + [ + 'kind' => 'OBJECT', + 'name' => 'VirtualProduct', + 'ofType' => null + ] + ] + ], + [ + 'kind' => 'INTERFACE', + 'name' => 'CustomizableOptionInterface', + 'description' => '', + 'fields' => [ [ 'name' => 'title', - 'description' => null, + 'description' => 'Comment for CustomizableOptionInterface', 'args' => [ ], @@ -3926,134 +2742,62 @@ ] ], 'inputFields' => null, - 'interfaces' => [ - [ - 'kind' => 'INTERFACE', - 'name' => 'CustomizableOptionInterface', - 'ofType' => null - ] - ], + 'interfaces' => null, 'enumValues' => null, - 'possibleTypes' => null - ], - [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableDropDownValue', - 'description' => '', - 'fields' => [ + 'possibleTypes' => [ [ - 'name' => 'option_type_id', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'kind' => 'OBJECT', + 'name' => 'CustomizableAreaOption', + 'ofType' => null ], [ - 'name' => 'price', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'kind' => 'OBJECT', + 'name' => 'CustomizableDateOption', + 'ofType' => null ], [ - 'name' => 'price_type', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'ENUM', - 'name' => 'PriceTypeEnum', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'kind' => 'OBJECT', + 'name' => 'CustomizableDropDownOption', + 'ofType' => null ], [ - 'name' => 'sku', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'kind' => 'OBJECT', + 'name' => 'CustomizableFieldOption', + 'ofType' => null ], [ - 'name' => 'title', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'kind' => 'OBJECT', + 'name' => 'CustomizableFileOption', + 'ofType' => null ], [ - 'name' => 'sort_order', - 'description' => null, - 'args' => [ - - ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ - - ], - 'enumValues' => null, - 'possibleTypes' => null + 'kind' => 'OBJECT', + 'name' => 'CustomizableRadioOption', + 'ofType' => null + ] + ] ], [ 'kind' => 'OBJECT', - 'name' => 'CustomizableFieldOption', + 'name' => 'ProductLinks', 'description' => '', 'fields' => [ [ - 'name' => 'value', + 'name' => 'sku', 'description' => null, 'args' => [ ], 'type' => [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableFieldValue', + 'kind' => 'SCALAR', + 'name' => 'String', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'product_sku', + 'name' => 'link_type', 'description' => null, 'args' => [ @@ -4067,7 +2811,7 @@ 'deprecationReason' => null ], [ - 'name' => 'title', + 'name' => 'linked_product_sku', 'description' => null, 'args' => [ @@ -4081,21 +2825,21 @@ 'deprecationReason' => null ], [ - 'name' => 'required', + 'name' => 'linked_product_type', 'description' => null, 'args' => [ ], 'type' => [ 'kind' => 'SCALAR', - 'name' => 'Boolean', + 'name' => 'String', 'ofType' => null ], 'isDeprecated' => false, 'deprecationReason' => null ], [ - 'name' => 'sort_order', + 'name' => 'position', 'description' => null, 'args' => [ @@ -4113,16 +2857,103 @@ 'interfaces' => [ [ 'kind' => 'INTERFACE', - 'name' => 'CustomizableOptionInterface', + 'name' => 'ProductLinksInterface', 'ofType' => null ] ], 'enumValues' => null, 'possibleTypes' => null ], + [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableAreaOption', + 'description'=> '', + 'fields'=> [ + [ + 'name'=> 'title', + 'description'=> 'Comment for title field for CustomizableAreaOption concrete type', + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], + [ + 'name'=> 'required', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Boolean', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], + [ + 'name'=> 'sort_order', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], + [ + 'name'=> 'value', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableAreaValue', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], + [ + 'name'=> 'product_sku', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ] + ], + 'inputFields'=> null, + 'interfaces'=> [ + [ + 'kind'=> 'INTERFACE', + 'name'=> 'CustomizableOptionInterface', + 'ofType'=> null + ] + ], + 'enumValues'=> null, + 'possibleTypes'=> null + ], [ 'kind' => 'OBJECT', - 'name' => 'CustomizableFieldValue', + 'name' => 'CustomizableAreaValue', 'description' => '', 'fields' => [ [ @@ -4190,95 +3021,121 @@ 'possibleTypes' => null ], [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableFileOption', + 'kind' => 'ENUM', + 'name' => 'PriceTypeEnum', 'description' => '', - 'fields' => [ + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => [ [ - 'name' => 'value', - 'description' => null, - 'args' => [ + 'name' => 'FIXED', + 'description' => '', + 'isDeprecated' => false + ], + [ + 'name' => 'PERCENT', + 'description' => '', + 'isDeprecated' => false + ], + [ + 'name' => 'DYNAMIC', + 'description' => '', + 'isDeprecated' => false + ] + ], + 'possibleTypes' => null + ], + [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableDateOption', + 'description'=> '', + 'fields'=> [ + [ + 'name'=> 'title', + 'description'=> 'This description should override interface comment.', + 'args'=> [ ], - 'type' => [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableFileValue', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'product_sku', - 'description' => null, - 'args' => [ + 'name'=> 'required', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Boolean', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'title', - 'description' => null, - 'args' => [ + 'name'=> 'sort_order', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'required', - 'description' => null, - 'args' => [ + 'name'=> 'value', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Boolean', - 'ofType' => null + 'type'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableDateValue', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'sort_order', - 'description' => null, - 'args' => [ + 'name'=> 'product_sku', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ] ], - 'inputFields' => null, - 'interfaces' => [ + 'inputFields'=> null, + 'interfaces'=> [ [ - 'kind' => 'INTERFACE', - 'name' => 'CustomizableOptionInterface', - 'ofType' => null + 'kind'=> 'INTERFACE', + 'name'=> 'CustomizableOptionInterface', + 'ofType'=> null ] ], - 'enumValues' => null, - 'possibleTypes' => null + 'enumValues'=> null, + 'possibleTypes'=> null ], [ 'kind' => 'OBJECT', - 'name' => 'CustomizableFileValue', + 'name' => 'CustomizableDateValue', 'description' => '', 'fields' => [ [ @@ -4322,867 +3179,1112 @@ ], 'isDeprecated' => false, 'deprecationReason' => null + ] + ], + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableDropDownOption', + 'description'=> '', + 'fields'=> [ + [ + 'name'=> 'title', + 'description'=> 'Comment for CustomizableOptionInterface', + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'file_extension', - 'description' => null, - 'args' => [ + 'name'=> 'required', + 'description'=> 'Comment for required field for CustomizableDropDownOption concrete type', + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Boolean', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'image_size_x', - 'description' => null, - 'args' => [ + 'name'=> 'sort_order', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'image_size_y', - 'description' => null, - 'args' => [ + 'name'=> 'value', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableDropDownValue', + 'ofType'=> null + ] ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ] ], - 'inputFields' => null, - 'interfaces' => [ - + 'inputFields'=> null, + 'interfaces'=> [ + [ + 'kind'=> 'INTERFACE', + 'name'=> 'CustomizableOptionInterface', + 'ofType'=> null + ] ], - 'enumValues' => null, - 'possibleTypes' => null + 'enumValues'=> null, + 'possibleTypes'=> null ], [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableRadioOption', - 'description' => '', - 'fields' => [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableDropDownValue', + 'description'=> '', + 'fields'=> [ [ - 'name' => 'value', - 'description' => null, - 'args' => [ + 'name'=> 'option_type_id', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableRadioValue', - 'ofType' => null - ] + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'title', - 'description' => null, - 'args' => [ + 'name'=> 'price', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Float', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'required', - 'description' => null, - 'args' => [ + 'name'=> 'price_type', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Boolean', - 'ofType' => null + 'type'=> [ + 'kind'=> 'ENUM', + 'name'=> 'PriceTypeEnum', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'sort_order', - 'description' => null, - 'args' => [ + 'name'=> 'sku', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], [ - 'kind' => 'INTERFACE', - 'name' => 'CustomizableOptionInterface', - 'ofType' => null + 'name'=> 'title', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], + [ + 'name'=> 'sort_order', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null ] ], - 'enumValues' => null, - 'possibleTypes' => null + 'inputFields'=> null, + 'interfaces'=> [ + + ], + 'enumValues'=> null, + 'possibleTypes'=> null ], [ - 'kind' => 'OBJECT', - 'name' => 'CustomizableRadioValue', - 'description' => '', - 'fields' => [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableFieldOption', + 'description'=> '', + 'fields'=> [ [ - 'name' => 'option_type_id', - 'description' => null, - 'args' => [ + 'name'=> 'title', + 'description'=> 'Comment for CustomizableOptionInterface', + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], + [ + 'name'=> 'required', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Boolean', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ], + [ + 'name'=> 'sort_order', + 'description'=> 'Comment for sort_order for CustomizableFieldOption concrete type', + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'price', - 'description' => null, - 'args' => [ + 'name'=> 'value', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null + 'type'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableFieldValue', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'price_type', - 'description' => null, - 'args' => [ + 'name'=> 'product_sku', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'ENUM', - 'name' => 'PriceTypeEnum', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null + ] + ], + 'inputFields'=> null, + 'interfaces'=> [ + [ + 'kind'=> 'INTERFACE', + 'name'=> 'CustomizableOptionInterface', + 'ofType'=> null + ] + ], + 'enumValues'=> null, + 'possibleTypes'=> null + ], + [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableFieldValue', + 'description'=> '', + 'fields'=> [ + [ + 'name'=> 'price', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Float', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'sku', - 'description' => null, - 'args' => [ + 'name'=> 'price_type', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'ENUM', + 'name'=> 'PriceTypeEnum', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'title', - 'description' => null, - 'args' => [ + 'name'=> 'sku', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'sort_order', - 'description' => null, - 'args' => [ + 'name'=> 'max_characters', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ] ], - 'inputFields' => null, - 'interfaces' => [ + 'inputFields'=> null, + 'interfaces'=> [ ], - 'enumValues' => null, - 'possibleTypes' => null + 'enumValues'=> null, + 'possibleTypes'=> null ], [ - 'kind' => 'OBJECT', - 'name' => 'VirtualProduct', - 'description' => '', - 'fields' => [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableFileOption', + 'description'=> '', + 'fields'=> [ [ - 'name' => 'id', - 'description' => null, - 'args' => [ + 'name'=> 'title', + 'description'=> 'Comment for CustomizableOptionInterface', + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'name', - 'description' => null, - 'args' => [ + 'name'=> 'required', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Boolean', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'sku', - 'description' => null, - 'args' => [ + 'name'=> 'sort_order', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'description', - 'description' => null, - 'args' => [ + 'name'=> 'value', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableFileValue', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'short_description', - 'description' => null, - 'args' => [ + 'name'=> 'product_sku', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ] + ], + 'inputFields'=> null, + 'interfaces'=> [ [ - 'name' => 'special_price', - 'description' => null, - 'args' => [ + 'kind'=> 'INTERFACE', + 'name'=> 'CustomizableOptionInterface', + 'ofType'=> null + ] + ], + 'enumValues'=> null, + 'possibleTypes'=> null + ], + [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableFileValue', + 'description'=> '', + 'fields'=> [ + [ + 'name'=> 'price', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Float', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'special_from_date', - 'description' => null, - 'args' => [ + 'name'=> 'price_type', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'ENUM', + 'name'=> 'PriceTypeEnum', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'special_to_date', - 'description' => null, - 'args' => [ + 'name'=> 'sku', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'attribute_set_id', - 'description' => null, - 'args' => [ + 'name'=> 'file_extension', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'meta_title', - 'description' => null, - 'args' => [ + 'name'=> 'image_size_x', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'meta_keyword', - 'description' => null, - 'args' => [ + 'name'=> 'image_size_y', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null - ], + 'isDeprecated'=> false, + 'deprecationReason'=> null + ] + ], + 'inputFields'=> null, + 'interfaces'=> [ + + ], + 'enumValues'=> null, + 'possibleTypes'=> null + ], + [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableRadioOption', + 'description'=> '', + 'fields'=> [ [ - 'name' => 'meta_description', - 'description' => null, - 'args' => [ + 'name'=> 'title', + 'description'=> 'Comment for CustomizableOptionInterface', + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'image', - 'description' => null, - 'args' => [ + 'name'=> 'required', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Boolean', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'small_image', - 'description' => null, - 'args' => [ + 'name'=> 'sort_order', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'thumbnail', - 'description' => null, - 'args' => [ + 'name'=> 'value', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableRadioValue', + 'ofType'=> null + ] ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null + ] + ], + 'inputFields'=> null, + 'interfaces'=> [ + [ + 'kind'=> 'INTERFACE', + 'name'=> 'CustomizableOptionInterface', + 'ofType'=> null + ] + ], + 'enumValues'=> null, + 'possibleTypes'=> null + ], + [ + 'kind'=> 'OBJECT', + 'name'=> 'CustomizableRadioValue', + 'description'=> '', + 'fields'=> [ + [ + 'name'=> 'option_type_id', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'new_from_date', - 'description' => null, - 'args' => [ + 'name'=> 'price', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Float', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'new_to_date', - 'description' => null, - 'args' => [ + 'name'=> 'price_type', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'ENUM', + 'name'=> 'PriceTypeEnum', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'tier_price', - 'description' => null, - 'args' => [ + 'name'=> 'sku', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Float', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'custom_design', - 'description' => null, - 'args' => [ + 'name'=> 'title', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'custom_design_from', - 'description' => null, - 'args' => [ + 'name'=> 'sort_order', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null + ] + ], + 'inputFields'=> null, + 'interfaces'=> [ + + ], + 'enumValues'=> null, + 'possibleTypes'=> null + ], + [ + 'kind'=> 'OBJECT', + 'name'=> 'VirtualProduct', + 'description'=> '', + 'fields'=> [ + [ + 'name'=> 'options', + 'description'=> null, + 'args'=> [ + + ], + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'INTERFACE', + 'name'=> 'CustomizableOptionInterface', + 'ofType'=> null + ] + ], + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'custom_design_to', - 'description' => null, - 'args' => [ + 'name'=> 'url_key', + 'description'=> 'comment for url_key inside ProductInterface type.', + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'custom_layout_update', - 'description' => null, - 'args' => [ + 'name'=> 'url_path', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'custom_layout', - 'description' => null, - 'args' => [ + 'name'=> 'id', + 'description'=> 'comment for [ProductInterface].', + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'page_layout', - 'description' => null, - 'args' => [ + 'name'=> 'name', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'category_ids', - 'description' => null, - 'args' => [ + 'name'=> 'sku', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null - ] + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'options_container', - 'description' => null, - 'args' => [ + 'name'=> 'special_price', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Float', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'image_label', - 'description' => null, - 'args' => [ + 'name'=> 'special_from_date', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'small_image_label', - 'description' => null, - 'args' => [ + 'name'=> 'attribute_set_id', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'thumbnail_label', - 'description' => null, - 'args' => [ + 'name'=> 'tier_price', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Float', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'created_at', - 'description' => null, - 'args' => [ + 'name'=> 'category_ids', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null + ] ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'updated_at', - 'description' => null, - 'args' => [ + 'name'=> 'updated_at', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'country_of_manufacture', - 'description' => null, - 'args' => [ + 'name'=> 'country_of_manufacture', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'type_id', - 'description' => null, - 'args' => [ + 'name'=> 'type_id', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'String', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'website_ids', - 'description' => null, - 'args' => [ + 'name'=> 'website_ids', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ] ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'category_links', - 'description' => null, - 'args' => [ + 'name'=> 'category_links', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'OBJECT', - 'name' => 'ProductCategoryLinks', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'ProductCategoryLinks', + 'ofType'=> null ] ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'product_links', - 'description' => null, - 'args' => [ + 'name'=> 'product_links', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'INTERFACE', - 'name' => 'ProductLinksInterface', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'INTERFACE', + 'name'=> 'ProductLinksInterface', + 'ofType'=> null ] ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'media_gallery_entries', - 'description' => null, - 'args' => [ + 'name'=> 'media_gallery_entries', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'OBJECT', - 'name' => 'MediaGalleryEntry', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'MediaGalleryEntry', + 'ofType'=> null ] ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'tier_prices', - 'description' => null, - 'args' => [ + 'name'=> 'tier_prices', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'OBJECT', - 'name' => 'ProductTierPrices', - 'ofType' => null + 'type'=> [ + 'kind'=> 'LIST', + 'name'=> null, + 'ofType'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'ProductTierPrices', + 'ofType'=> null ] ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'price', - 'description' => null, - 'args' => [ + 'name'=> 'price', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'OBJECT', - 'name' => 'ProductPrices', - 'ofType' => null + 'type'=> [ + 'kind'=> 'OBJECT', + 'name'=> 'ProductPrices', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null ], [ - 'name' => 'gift_message_available', - 'description' => null, - 'args' => [ + 'name'=> 'manufacturer', + 'description'=> null, + 'args'=> [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null + 'type'=> [ + 'kind'=> 'SCALAR', + 'name'=> 'Int', + 'ofType'=> null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated'=> false, + 'deprecationReason'=> null + ] + ], + 'inputFields'=> null, + 'interfaces'=> [ + [ + 'kind'=> 'INTERFACE', + 'name'=> 'ProductInterface', + 'ofType'=> null ], [ - 'name' => 'options', - 'description' => null, - 'args' => [ + 'kind'=> 'INTERFACE', + 'name'=> 'CustomizableProductInterface', + 'ofType'=> null + ] + ], + 'enumValues'=> null, + 'possibleTypes'=> null + ], + [ + 'kind' => 'OBJECT', + 'name' => 'EntityUrl', + 'description' => '', + 'fields' => [ + [ + 'name' => 'id', + 'description' => null, + 'args' => [ ], - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'INTERFACE', - 'name' => 'CustomizableOptionInterface', - 'ofType' => null - ] + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'Int', + 'ofType' => null ], - 'isDeprecated' => false, - 'deprecationReason' => null + 'isDeprecated' => false, + 'deprecationReason' => null ], [ - 'name' => 'manufacturer', - 'description' => null, - 'args' => [ + 'name' => 'canonical_url', + 'description' => null, + 'args' => [ ], - 'type' => [ - 'kind' => 'SCALAR', - 'name' => 'Int', - 'ofType' => null + 'type' => [ + 'kind' => 'SCALAR', + 'name' => 'String', + 'ofType' => null ], - 'isDeprecated' => false, - 'deprecationReason' => null - ] - ], - 'inputFields' => null, - 'interfaces' => [ - [ - 'kind' => 'INTERFACE', - 'name' => 'ProductInterface', - 'ofType' => null + 'isDeprecated' => false, + 'deprecationReason' => null ], [ - 'kind' => 'INTERFACE', - 'name' => 'CustomizableProductInterface', - 'ofType' => null + 'name' => 'type', + 'description' => null, + 'args' => [ + + ], + 'type' => [ + 'kind' => 'ENUM', + 'name' => 'UrlRewriteEntityTypeEnum', + 'ofType' => null + ], + 'isDeprecated' => false, + 'deprecationReason' => null ] ], - 'enumValues' => null, - 'possibleTypes' => null + 'inputFields' => null, + 'interfaces' => [ + + ], + 'enumValues' => null, + 'possibleTypes' => null + ], + [ + 'kind' => 'ENUM', + 'name' => 'UrlRewriteEntityTypeEnum', + 'description' => 'Comment for empty Enum', + 'fields' => null, + 'inputFields' => null, + 'interfaces' => null, + 'enumValues' => [ + + ], + 'possibleTypes' => null ] ]; From fcecfe2a820cefb134175ef8e05eaea7fb17d29c Mon Sep 17 00:00:00 2001 From: Robert He Date: Mon, 26 Mar 2018 15:22:43 -0500 Subject: [PATCH 238/668] MAGETWO-71622: [UI Component] Color Picker - implemented basic UI component Color Picker --- app/code/Magento/Ui/etc/ui_components.xsd | 1 + app/code/Magento/Ui/etc/ui_configuration.xsd | 10 + app/code/Magento/Ui/etc/ui_definition.xsd | 1 + .../Magento/Ui/view/base/requirejs-config.js | 1 + .../base/ui_component/etc/definition.map.xml | 9 + .../view/base/ui_component/etc/definition.xml | 1 + .../etc/definition/colorPicker.xsd | 31 + .../base/web/js/form/element/colorPicker.js | 67 + .../web/js/lib/knockout/bindings/bootstrap.js | 3 +- .../js/lib/knockout/bindings/colorPicker.js | 31 + .../templates/form/element/colorPicker.html | 19 + .../Magento_Ui/web/css/source/_module.less | 1 + .../web/css/source/module/spectrum.less | 508 ++++ lib/web/jquery/spectrum.js | 2323 +++++++++++++++++ 14 files changed, 3005 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Ui/view/base/ui_component/etc/definition/colorPicker.xsd create mode 100644 app/code/Magento/Ui/view/base/web/js/form/element/colorPicker.js create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/colorPicker.js create mode 100644 app/code/Magento/Ui/view/base/web/templates/form/element/colorPicker.html create mode 100644 app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/spectrum.less create mode 100644 lib/web/jquery/spectrum.js diff --git a/app/code/Magento/Ui/etc/ui_components.xsd b/app/code/Magento/Ui/etc/ui_components.xsd index 3d3c0d11bb454..be3de0908402c 100644 --- a/app/code/Magento/Ui/etc/ui_components.xsd +++ b/app/code/Magento/Ui/etc/ui_components.xsd @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Ui/etc/ui_configuration.xsd b/app/code/Magento/Ui/etc/ui_configuration.xsd index 5783323b53188..7dc71a2c9a94f 100644 --- a/app/code/Magento/Ui/etc/ui_configuration.xsd +++ b/app/code/Magento/Ui/etc/ui_configuration.xsd @@ -19,6 +19,7 @@ + @@ -65,6 +66,7 @@ + @@ -157,6 +159,7 @@ + @@ -780,4 +783,11 @@ + + + + ColorPicker + + + diff --git a/app/code/Magento/Ui/etc/ui_definition.xsd b/app/code/Magento/Ui/etc/ui_definition.xsd index d1787309d051e..cb48cbd44240b 100644 --- a/app/code/Magento/Ui/etc/ui_definition.xsd +++ b/app/code/Magento/Ui/etc/ui_definition.xsd @@ -28,6 +28,7 @@ + diff --git a/app/code/Magento/Ui/view/base/requirejs-config.js b/app/code/Magento/Ui/view/base/requirejs-config.js index e91fe309dd19c..cb41189839ec3 100644 --- a/app/code/Magento/Ui/view/base/requirejs-config.js +++ b/app/code/Magento/Ui/view/base/requirejs-config.js @@ -12,6 +12,7 @@ var config = { paths: { 'ui/template': 'Magento_Ui/templates', 'tinymce4': 'tiny_mce_4/tinymce.min', + 'spectrum': 'jquery/spectrum', 'wysiwygAdapter': 'mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter' }, map: { diff --git a/app/code/Magento/Ui/view/base/ui_component/etc/definition.map.xml b/app/code/Magento/Ui/view/base/ui_component/etc/definition.map.xml index cc3162e2b9acb..c55c4cff76316 100644 --- a/app/code/Magento/Ui/view/base/ui_component/etc/definition.map.xml +++ b/app/code/Magento/Ui/view/base/ui_component/etc/definition.map.xml @@ -103,6 +103,15 @@ + + + + + settings/initialCOlor + + + + diff --git a/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml index 4b4eac517a299..48c7c8951ab08 100755 --- a/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml +++ b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml @@ -149,6 +149,7 @@ wysiwyg + diff --git a/app/code/Magento/Ui/view/base/ui_component/etc/definition/colorPicker.xsd b/app/code/Magento/Ui/view/base/ui_component/etc/definition/colorPicker.xsd new file mode 100644 index 0000000000000..9ae157b2028ac --- /dev/null +++ b/app/code/Magento/Ui/view/base/ui_component/etc/definition/colorPicker.xsd @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/colorPicker.js b/app/code/Magento/Ui/view/base/web/js/form/element/colorPicker.js new file mode 100644 index 0000000000000..b3fb0429d880f --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/form/element/colorPicker.js @@ -0,0 +1,67 @@ + +/** + * @api + */ +define([ + 'jquery', + 'underscore', + 'uiLayout', + 'mage/translate', + 'Magento_Ui/js/form/element/abstract', + 'spectrum' +], function ($, _, layout, $t, Abstract, spectrum) { + 'use strict'; + + var defaultColorPalette = [ + ['rgb(0,0,0)', 'rgb(52,52,52)', 'rgb(83,83,83)', 'rgb(135,135,135)', 'rgb(193,193,193)', 'rgb(234,234,234)', 'rgb(240,240,240)', 'rgb(255,255,255)'], + ['rgb(252,0,9)', 'rgb(253,135,10)', 'rgb(255,255,13)', 'rgb(35,255,9)', 'rgb(33,255,255)', 'rgb(0,0,254)', 'rgb(132,0,254)', 'rgb(251,0,255)'], + ['rgb(240,192,194)', 'rgb(251,223,194)', 'rgb(255,241,193)', 'rgb(210,230,201)', 'rgb(199,217,220)', 'rgb(197,219,240)', 'rgb(208,200,227)', 'rgb(229,199,212)'], + ['rgb(228,133,135)', 'rgb(246,193,139)', 'rgb(254,225,136)', 'rgb(168,208,152)', 'rgb(146,184,190)', 'rgb(143,184,227)', 'rgb(165,148,204)', 'rgb(202,147,175)'], + ['rgb(214,78,83)', 'rgb(243,163,88)', 'rgb(254,211,83)', 'rgb(130,187,106)', 'rgb(99,149,159)', 'rgb(93,150,211)', 'rgb(123,100,182)', 'rgb(180,100,142)'], + ['rgb(190,0,5)', 'rgb(222,126,44)', 'rgb(236,183,39)', 'rgb(89,155,61)', 'rgb(55,110,123)', 'rgb(49,112,185)', 'rgb(83,55,150)', 'rgb(147,55,101)'], + ['rgb(133,0,3)', 'rgb(163,74,10)', 'rgb(177,127,7)', 'rgb(45,101,23)', 'rgb(18,62,74)', 'rgb(14,62,129)', 'rgb(40,15,97)', 'rgb(95,16,55)'], + ['rgb(81,0,1)', 'rgb(100,48,7)', 'rgb(107,78,3)', 'rgb(31,63,16)', 'rgb(13,39,46)', 'rgb(10,40,79)', 'rgb(24,12,59)', 'rgb(59,10,36)'] + ]; + + return Abstract.extend({ + + defaults: { + colorPickerConfig: { + showInput: true, + allowEmpty: true, + showInitial: false, + showPalette: true, + showAlpha: true, + chooseText: "Apply", + cancelText: "Cancel", + showSelectionPalette: true, + maxSelectionSize: 64, + preferredFormat: "rgb", + palette: defaultColorPalette + } + }, + + /** + * Initializes observable properties of instance + * + * @returns {Abstract} Chainable. + */ + initObservable: function () { + this._super() + .observe('componentTemplate'); + return this; + }, + + /** + * Invokes initialize method of parent class, + * contains initialization logic + */ + initialize: function () { + this._super(); + + return this; + } + + }); +}); + \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bootstrap.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bootstrap.js index b29d10a143117..f4c1c6d3cb9f8 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bootstrap.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bootstrap.js @@ -37,6 +37,7 @@ define(function (require) { bindHtml: require('./bind-html'), tooltip: require('./tooltip'), repeat: require('knockoutjs/knockout-repeat'), - fastForEach: require('knockoutjs/knockout-fast-foreach') + fastForEach: require('knockoutjs/knockout-fast-foreach'), + colorPicker: require('./colorPicker') }; }); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/colorPicker.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/colorPicker.js new file mode 100644 index 0000000000000..5dc3b6b69393f --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/colorPicker.js @@ -0,0 +1,31 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'ko', + 'jquery', + '../template/renderer', + 'spectrum' +], function (ko, $, renderer, spectrum) { + 'use strict'; + + ko.bindingHandlers.colorPicker = { + + /** + * Binding init callback. + * + * @param {*} element + * @param {Function} valueAccessor + * @param {Function} allBindings + * @param {Object} viewModel + */ + init: function (element, valueAccessor, allBindings, viewModel) { + var config = valueAccessor(); + + $(element).spectrum(config); + } + }; + + renderer.addAttribute('colorPicker'); +}); diff --git a/app/code/Magento/Ui/view/base/web/templates/form/element/colorPicker.html b/app/code/Magento/Ui/view/base/web/templates/form/element/colorPicker.html new file mode 100644 index 0000000000000..b999aff226705 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/form/element/colorPicker.html @@ -0,0 +1,19 @@ + +
+ +
+ + + +
+
\ No newline at end of file diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/_module.less index e05e81d737f14..87333cf11f5cf 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/_module.less +++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/_module.less @@ -4,3 +4,4 @@ // */ @import 'module/_data-grid.less'; +@import 'module/spectrum.less'; diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/spectrum.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/spectrum.less new file mode 100644 index 0000000000000..89880abda1d84 --- /dev/null +++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/spectrum.less @@ -0,0 +1,508 @@ + +/*** +Spectrum Colorpicker v1.8.0 +https://github.com/bgrins/spectrum +Author: Brian Grinstead +License: MIT +***/ + +.sp-container { + position:absolute; + top:0; + left:0; + display:inline-block; + *display: inline; + *zoom: 1; + /* https://github.com/bgrins/spectrum/issues/40 */ + z-index: 9999994; + overflow: hidden; +} +.sp-container.sp-flat { + position: relative; +} + +/* Fix for * { box-sizing: border-box; } */ +.sp-container, +.sp-container * { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +/* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */ +.sp-top { + position:relative; + width: 100%; + display:inline-block; +} +.sp-top-inner { + position:absolute; + top:0; + left:0; + bottom:0; + right:0; +} +.sp-color { + position: absolute; + top:0; + left:0; + bottom:0; + right:20%; +} +.sp-hue { + position: absolute; + top:0; + right:0; + bottom:0; + left:84%; + height: 100%; +} + +.sp-clear-enabled .sp-hue { + top:33px; + height: 77.5%; +} + +.sp-fill { + padding-top: 80%; +} +.sp-sat, .sp-val { + position: absolute; + top:0; + left:0; + right:0; + bottom:0; +} + +.sp-alpha-enabled .sp-top { + margin-bottom: 18px; +} +.sp-alpha-enabled .sp-alpha { + display: block; +} +.sp-alpha-handle { + position:absolute; + top:-4px; + bottom: -4px; + width: 6px; + left: 50%; + cursor: pointer; + border: 1px solid black; + background: white; + opacity: .8; +} +.sp-alpha { + display: none; + position: absolute; + bottom: -14px; + right: 0; + left: 0; + height: 8px; +} +.sp-alpha-inner { + border: solid 1px #333; +} + +.sp-clear { + display: none; +} + +.sp-clear.sp-clear-display { + background-position: center; +} + +.sp-clear-enabled .sp-clear { + display: block; + position:absolute; + top:0px; + right:0; + bottom:0; + left:84%; + height: 28px; +} + +/* Don't allow text selection */ +.sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-clear, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button { + -webkit-user-select:none; + -moz-user-select: -moz-none; + -o-user-select:none; + user-select: none; +} + +.sp-container.sp-input-disabled .sp-input-container { + display: none; +} +.sp-container.sp-buttons-disabled .sp-button-container { + display: none; +} +.sp-container.sp-palette-buttons-disabled .sp-palette-button-container { + display: none; +} +.sp-palette-only .sp-picker-container { + display: none; +} +.sp-palette-disabled .sp-palette-container { + display: none; +} + +.sp-initial-disabled .sp-initial { + display: none; +} + + +/* Gradients for hue, saturation and value instead of images. Not pretty... but it works */ +.sp-sat { + background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0))); + background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0)); + background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); + background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); + background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); + background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)"; + filter : progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr='#FFFFFFFF', endColorstr='#00CC9A81'); +} +.sp-val { + background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0))); + background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0)); + background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); + background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); + background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); + background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)"; + filter : progid:DXImageTransform.Microsoft.gradient(startColorstr='#00CC9A81', endColorstr='#FF000000'); +} + +.sp-hue { + background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); + background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); + background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); + background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000)); + background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); + background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); +} + +/* IE filters do not support multiple color stops. + Generate 6 divs, line them up, and do two color gradients for each. + Yes, really. + */ +.sp-1 { + height:17%; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00'); +} +.sp-2 { + height:16%; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00'); +} +.sp-3 { + height:17%; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff'); +} +.sp-4 { + height:17%; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff'); +} +.sp-5 { + height:16%; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff'); +} +.sp-6 { + height:17%; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000'); +} + +.sp-hidden { + display: none !important; +} + +/* Clearfix hack */ +.sp-cf:before, .sp-cf:after { content: ""; display: table; } +.sp-cf:after { clear: both; } +.sp-cf { *zoom: 1; } + +/* Mobile devices, make hue slider bigger so it is easier to slide */ +@media (max-device-width: 480px) { + .sp-color { right: 40%; } + .sp-hue { left: 63%; } + .sp-fill { padding-top: 60%; } +} +.sp-dragger { + border-radius: 5px; + height: 5px; + width: 5px; + border: 1px solid #fff; + background: #000; + cursor: pointer; + position:absolute; + top:0; + left: 0; +} +.sp-slider { + position: absolute; + top:0; + cursor:pointer; + height: 3px; + left: -1px; + right: -1px; + border: 1px solid #000; + background: white; + opacity: .8; +} + +/* +Theme authors: +Here are the basic themeable display options (colors, fonts, global widths). +See http://bgrins.github.io/spectrum/themes/ for instructions. +*/ + +.sp-container { + border-radius: 0; + background-color: #ffffff; + border: solid 1px #1979c3; + padding: 0; +} +.sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue, .sp-clear { + font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; +} +.sp-top { + margin-bottom: 3px; +} +.sp-color, .sp-hue, .sp-clear { + border: solid 1px #666; +} + +/* Input */ +.sp-input-container { + float:right; + width: 100px; + margin-bottom: 4px; +} +.sp-initial-disabled .sp-input-container { + width: 100%; +} +.sp-input { + font-size: 12px !important; + border: 1px inset; + padding: 4px 5px; + margin: 0; + width: 100%; + background:transparent; + border-radius: 3px; + color: #222; +} +.sp-input:focus { + border: 1px solid orange; +} +.sp-input.sp-validation-error { + border: 1px solid red; + background: #fdd; +} +.sp-picker-container , .sp-palette-container { + float:left; + position: relative; + padding: 10px; + padding-bottom: 300px; + margin-bottom: -290px; +} +.sp-picker-container { + width: 172px; + border-left: solid 1px #fff; +} + +/* Palettes */ +.sp-palette-container { + border-right: solid 1px #ccc; +} + +.sp-palette-only .sp-palette-container { + border: 0; +} + +.sp-palette .sp-thumb-el { + display: block; + position:relative; + float:left; + width: 24px; + height: 15px; + margin: 3px; + cursor: pointer; + border:solid 2px transparent; +} +.sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active { + border-color: orange; +} +.sp-thumb-el { + position:relative; +} + +/* Initial */ +.sp-initial { + float: left; + border: solid 1px #333; +} +.sp-initial span { + width: 30px; + height: 25px; + border:none; + display:block; + float:left; + margin:0; +} + +.sp-initial .sp-clear-display { + background-position: center; +} + +/* Buttons */ +.sp-palette-button-container, +.sp-button-container { + float: right; +} + +/* Replacer (the little preview div that shows up instead of the ) */ +.sp-replacer { + margin:0; + overflow:hidden; + cursor:pointer; + padding: 4px; + display:inline-block; + *zoom: 1; + *display: inline; + border: solid 1px #91765d; + background: #eee; + color: #333; + vertical-align: middle; +} +.sp-replacer:hover, .sp-replacer.sp-active { + border-color: #F0C49B; + color: #111; +} +.sp-replacer.sp-disabled { + cursor:default; + border-color: silver; + color: silver; +} +.sp-dd { + padding: 2px 0; + height: 16px; + line-height: 16px; + float:left; + font-size:10px; +} +.sp-preview { + position:relative; + width:25px; + height: 20px; + border: solid 1px #222; + margin-right: 5px; + float:left; + z-index: 0; +} + +.sp-palette { + *width: 220px; + max-width: 220px; +} +.sp-palette .sp-thumb-el { + width:16px; + height: 16px; + margin:2px 1px; + border: solid 1px #d0d0d0; +} + +.sp-container { + padding-bottom:0; +} + + +/* Buttons: http://hellohappy.org/css3-buttons/ */ +.sp-container button { + background-color: #eeeeee; + background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc); + background-image: -moz-linear-gradient(top, #eeeeee, #cccccc); + background-image: -ms-linear-gradient(top, #eeeeee, #cccccc); + background-image: -o-linear-gradient(top, #eeeeee, #cccccc); + background-image: linear-gradient(to bottom, #eeeeee, #cccccc); + border: 1px solid #ccc; + border-bottom: 1px solid #bbb; + border-radius: 3px; + color: #333; + font-size: 14px; + line-height: 1; + padding: 5px 4px; + text-align: center; + text-shadow: 0 1px 0 #eee; + vertical-align: middle; +} +.sp-container button:hover { + background-color: #dddddd; + background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb); + background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb); + background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb); + background-image: -o-linear-gradient(top, #dddddd, #bbbbbb); + background-image: linear-gradient(to bottom, #dddddd, #bbbbbb); + border: 1px solid #bbb; + border-bottom: 1px solid #999; + cursor: pointer; + text-shadow: 0 1px 0 #ddd; +} +.sp-container button:active { + border: 1px solid #aaa; + border-bottom: 1px solid #888; + -webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; + -moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; + -ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; + -o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; + box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; +} +.sp-cancel { + font-size: 11px; + color: #1979c3 !important; + margin:0; + padding:2px; + margin-right: 15px; + vertical-align: middle; + text-decoration:none; + +} +.sp-cancel:hover { + color: #d93f3f !important; + text-decoration: underline; +} + + +.sp-palette span:hover, .sp-palette span.sp-thumb-active { + border-color: #000; +} + +.sp-preview, .sp-alpha, .sp-thumb-el { + position:relative; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); +} +.sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner { + display:block; + position:absolute; + top:0;left:0;bottom:0;right:0; +} + +.sp-palette .sp-thumb-inner { + background-position: 50% 50%; + background-repeat: no-repeat; +} + +.sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=); +} + +.sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=); +} + +.sp-clear-display { + background-repeat:no-repeat; + background-position: center; + background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==); +} diff --git a/lib/web/jquery/spectrum.js b/lib/web/jquery/spectrum.js new file mode 100644 index 0000000000000..7e4933934fc63 --- /dev/null +++ b/lib/web/jquery/spectrum.js @@ -0,0 +1,2323 @@ +// Spectrum Colorpicker v1.8.0 +// https://github.com/bgrins/spectrum +// Author: Brian Grinstead +// License: MIT + +(function (factory) { + "use strict"; + + if (typeof define === 'function' && define.amd) { // AMD + define(['jquery'], factory); + } + else if (typeof exports == "object" && typeof module == "object") { // CommonJS + module.exports = factory(require('jquery')); + } + else { // Browser + factory(jQuery); + } +})(function($, undefined) { + "use strict"; + + var defaultOpts = { + + // Callbacks + beforeShow: noop, + move: noop, + change: noop, + show: noop, + hide: noop, + + // Options + color: false, + flat: false, + showInput: false, + allowEmpty: false, + showButtons: true, + clickoutFiresChange: true, + showInitial: false, + showPalette: false, + showPaletteOnly: false, + hideAfterPaletteSelect: false, + togglePaletteOnly: false, + showSelectionPalette: true, + localStorageKey: false, + appendTo: "body", + maxSelectionSize: 7, + cancelText: "cancel", + chooseText: "choose", + togglePaletteMoreText: "more", + togglePaletteLessText: "less", + clearText: "Clear Color Selection", + noColorSelectedText: "No Color Selected", + preferredFormat: false, + className: "", // Deprecated - use containerClassName and replacerClassName instead. + containerClassName: "", + replacerClassName: "", + showAlpha: false, + theme: "sp-light", + palette: [["#ffffff", "#000000", "#ff0000", "#ff8000", "#ffff00", "#008000", "#0000ff", "#4b0082", "#9400d3"]], + selectionPalette: [], + disabled: false, + offset: null + }, + spectrums = [], + IE = !!/msie/i.exec( window.navigator.userAgent ), + rgbaSupport = (function() { + function contains( str, substr ) { + return !!~('' + str).indexOf(substr); + } + + var elem = document.createElement('div'); + var style = elem.style; + style.cssText = 'background-color:rgba(0,0,0,.5)'; + return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla'); + })(), + replaceInput = [ + "
", + "
", + "
", + "
" + ].join(''), + markup = (function () { + + // IE does not support gradients with multiple stops, so we need to simulate + // that for the rainbow slider with 8 divs that each have a single gradient + var gradientFix = ""; + if (IE) { + for (var i = 1; i <= 6; i++) { + gradientFix += "
"; + } + } + + return [ + "
", + "
", + "
", + "
", + "", + "
", + "
", + "
", + "
", + "
", + "
", + "
", + "
", + "
", + "
", + "
", + "
", + "
", + "
", + "
", + "
", + "
", + gradientFix, + "
", + "
", + "
", + "
", + "
", + "", + "
", + "
", + "
", + "", + "", + "
", + "
", + "
" + ].join(""); + })(); + + function paletteTemplate (p, color, className, opts) { + var html = []; + for (var i = 0; i < p.length; i++) { + var current = p[i]; + if(current) { + var tiny = tinycolor(current); + var c = tiny.toHsl().l < 0.5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light"; + c += (tinycolor.equals(color, current)) ? " sp-thumb-active" : ""; + var formattedString = tiny.toString(opts.preferredFormat || "rgb"); + var swatchStyle = rgbaSupport ? ("background-color:" + tiny.toRgbString()) : "filter:" + tiny.toFilter(); + html.push(''); + } else { + var cls = 'sp-clear-display'; + html.push($('
') + .append($('') + .attr('title', opts.noColorSelectedText) + ) + .html() + ); + } + } + return "
" + html.join('') + "
"; + } + + function hideAll() { + for (var i = 0; i < spectrums.length; i++) { + if (spectrums[i]) { + spectrums[i].hide(); + } + } + } + + function instanceOptions(o, callbackContext) { + var opts = $.extend({}, defaultOpts, o); + opts.callbacks = { + 'move': bind(opts.move, callbackContext), + 'change': bind(opts.change, callbackContext), + 'show': bind(opts.show, callbackContext), + 'hide': bind(opts.hide, callbackContext), + 'beforeShow': bind(opts.beforeShow, callbackContext) + }; + + return opts; + } + + function spectrum(element, o) { + + var opts = instanceOptions(o, element), + flat = opts.flat, + showSelectionPalette = opts.showSelectionPalette, + localStorageKey = opts.localStorageKey, + theme = opts.theme, + callbacks = opts.callbacks, + resize = throttle(reflow, 10), + visible = false, + isDragging = false, + dragWidth = 0, + dragHeight = 0, + dragHelperHeight = 0, + slideHeight = 0, + slideWidth = 0, + alphaWidth = 0, + alphaSlideHelperWidth = 0, + slideHelperHeight = 0, + currentHue = 0, + currentSaturation = 0, + currentValue = 0, + currentAlpha = 1, + palette = [], + paletteArray = [], + paletteLookup = {}, + selectionPalette = opts.selectionPalette.slice(0), + maxSelectionSize = opts.maxSelectionSize, + draggingClass = "sp-dragging", + shiftMovementDirection = null; + + var doc = element.ownerDocument, + body = doc.body, + boundElement = $(element), + disabled = false, + container = $(markup, doc).addClass(theme), + pickerContainer = container.find(".sp-picker-container"), + dragger = container.find(".sp-color"), + dragHelper = container.find(".sp-dragger"), + slider = container.find(".sp-hue"), + slideHelper = container.find(".sp-slider"), + alphaSliderInner = container.find(".sp-alpha-inner"), + alphaSlider = container.find(".sp-alpha"), + alphaSlideHelper = container.find(".sp-alpha-handle"), + textInput = container.find(".sp-input"), + paletteContainer = container.find(".sp-palette"), + initialColorContainer = container.find(".sp-initial"), + cancelButton = container.find(".sp-cancel"), + clearButton = container.find(".sp-clear"), + chooseButton = container.find(".sp-choose"), + toggleButton = container.find(".sp-palette-toggle"), + isInput = boundElement.is("input"), + isInputTypeColor = isInput && boundElement.attr("type") === "color" && inputTypeColorSupport(), + shouldReplace = isInput && !flat, + replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName) : $([]), + offsetElement = (shouldReplace) ? replacer : boundElement, + previewElement = replacer.find(".sp-preview-inner"), + initialColor = opts.color || (isInput && boundElement.val()), + colorOnShow = false, + currentPreferredFormat = opts.preferredFormat, + clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange, + isEmpty = !initialColor, + allowEmpty = opts.allowEmpty && !isInputTypeColor; + + function applyOptions() { + + if (opts.showPaletteOnly) { + opts.showPalette = true; + } + + toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText); + + if (opts.palette) { + palette = opts.palette.slice(0); + paletteArray = $.isArray(palette[0]) ? palette : [palette]; + paletteLookup = {}; + for (var i = 0; i < paletteArray.length; i++) { + for (var j = 0; j < paletteArray[i].length; j++) { + var rgb = tinycolor(paletteArray[i][j]).toRgbString(); + paletteLookup[rgb] = true; + } + } + } + + container.toggleClass("sp-flat", flat); + container.toggleClass("sp-input-disabled", !opts.showInput); + container.toggleClass("sp-alpha-enabled", opts.showAlpha); + container.toggleClass("sp-clear-enabled", allowEmpty); + container.toggleClass("sp-buttons-disabled", !opts.showButtons); + container.toggleClass("sp-palette-buttons-disabled", !opts.togglePaletteOnly); + container.toggleClass("sp-palette-disabled", !opts.showPalette); + container.toggleClass("sp-palette-only", opts.showPaletteOnly); + container.toggleClass("sp-initial-disabled", !opts.showInitial); + container.addClass(opts.className).addClass(opts.containerClassName); + + reflow(); + } + + function initialize() { + + if (IE) { + container.find("*:not(input)").attr("unselectable", "on"); + } + + applyOptions(); + + if (shouldReplace) { + boundElement.after(replacer).hide(); + } + + if (!allowEmpty) { + clearButton.hide(); + } + + if (flat) { + boundElement.after(container).hide(); + } + else { + + var appendTo = opts.appendTo === "parent" ? boundElement.parent() : $(opts.appendTo); + if (appendTo.length !== 1) { + appendTo = $("body"); + } + + appendTo.append(container); + } + + updateSelectionPaletteFromStorage(); + + offsetElement.bind("click.spectrum touchstart.spectrum", function (e) { + if (!disabled) { + toggle(); + } + + e.stopPropagation(); + + if (!$(e.target).is("input")) { + e.preventDefault(); + } + }); + + if(boundElement.is(":disabled") || (opts.disabled === true)) { + disable(); + } + + // Prevent clicks from bubbling up to document. This would cause it to be hidden. + container.click(stopPropagation); + + // Handle user typed input + textInput.change(setFromTextInput); + textInput.bind("paste", function () { + setTimeout(setFromTextInput, 1); + }); + textInput.keydown(function (e) { if (e.keyCode == 13) { setFromTextInput(); } }); + + cancelButton.text(opts.cancelText); + cancelButton.bind("click.spectrum", function (e) { + e.stopPropagation(); + e.preventDefault(); + revert(); + hide(); + }); + + clearButton.attr("title", opts.clearText); + clearButton.bind("click.spectrum", function (e) { + e.stopPropagation(); + e.preventDefault(); + isEmpty = true; + move(); + + if(flat) { + //for the flat style, this is a change event + updateOriginalInput(true); + } + }); + + chooseButton.text(opts.chooseText); + chooseButton.bind("click.spectrum", function (e) { + e.stopPropagation(); + e.preventDefault(); + + if (IE && textInput.is(":focus")) { + textInput.trigger('change'); + } + + if (isValid()) { + updateOriginalInput(true); + hide(); + } + }); + + toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText); + toggleButton.bind("click.spectrum", function (e) { + e.stopPropagation(); + e.preventDefault(); + + opts.showPaletteOnly = !opts.showPaletteOnly; + + // To make sure the Picker area is drawn on the right, next to the + // Palette area (and not below the palette), first move the Palette + // to the left to make space for the picker, plus 5px extra. + // The 'applyOptions' function puts the whole container back into place + // and takes care of the button-text and the sp-palette-only CSS class. + if (!opts.showPaletteOnly && !flat) { + container.css('left', '-=' + (pickerContainer.outerWidth(true) + 5)); + } + applyOptions(); + }); + + draggable(alphaSlider, function (dragX, dragY, e) { + currentAlpha = (dragX / alphaWidth); + isEmpty = false; + if (e.shiftKey) { + currentAlpha = Math.round(currentAlpha * 10) / 10; + } + + move(); + }, dragStart, dragStop); + + draggable(slider, function (dragX, dragY) { + currentHue = parseFloat(dragY / slideHeight); + isEmpty = false; + if (!opts.showAlpha) { + currentAlpha = 1; + } + move(); + }, dragStart, dragStop); + + draggable(dragger, function (dragX, dragY, e) { + + // shift+drag should snap the movement to either the x or y axis. + if (!e.shiftKey) { + shiftMovementDirection = null; + } + else if (!shiftMovementDirection) { + var oldDragX = currentSaturation * dragWidth; + var oldDragY = dragHeight - (currentValue * dragHeight); + var furtherFromX = Math.abs(dragX - oldDragX) > Math.abs(dragY - oldDragY); + + shiftMovementDirection = furtherFromX ? "x" : "y"; + } + + var setSaturation = !shiftMovementDirection || shiftMovementDirection === "x"; + var setValue = !shiftMovementDirection || shiftMovementDirection === "y"; + + if (setSaturation) { + currentSaturation = parseFloat(dragX / dragWidth); + } + if (setValue) { + currentValue = parseFloat((dragHeight - dragY) / dragHeight); + } + + isEmpty = false; + if (!opts.showAlpha) { + currentAlpha = 1; + } + + move(); + + }, dragStart, dragStop); + + if (!!initialColor) { + set(initialColor); + + // In case color was black - update the preview UI and set the format + // since the set function will not run (default color is black). + updateUI(); + currentPreferredFormat = opts.preferredFormat || tinycolor(initialColor).format; + + addColorToSelectionPalette(initialColor); + } + else { + updateUI(); + } + + if (flat) { + show(); + } + + function paletteElementClick(e) { + if (e.data && e.data.ignore) { + set($(e.target).closest(".sp-thumb-el").data("color")); + move(); + } + else { + set($(e.target).closest(".sp-thumb-el").data("color")); + move(); + updateOriginalInput(true); + if (opts.hideAfterPaletteSelect) { + hide(); + } + } + + return false; + } + + var paletteEvent = IE ? "mousedown.spectrum" : "click.spectrum touchstart.spectrum"; + paletteContainer.delegate(".sp-thumb-el", paletteEvent, paletteElementClick); + initialColorContainer.delegate(".sp-thumb-el:nth-child(1)", paletteEvent, { ignore: true }, paletteElementClick); + } + + function updateSelectionPaletteFromStorage() { + + if (localStorageKey && window.localStorage) { + + // Migrate old palettes over to new format. May want to remove this eventually. + try { + var oldPalette = window.localStorage[localStorageKey].split(",#"); + if (oldPalette.length > 1) { + delete window.localStorage[localStorageKey]; + $.each(oldPalette, function(i, c) { + addColorToSelectionPalette(c); + }); + } + } + catch(e) { } + + try { + selectionPalette = window.localStorage[localStorageKey].split(";"); + } + catch (e) { } + } + } + + function addColorToSelectionPalette(color) { + if (showSelectionPalette) { + var rgb = tinycolor(color).toRgbString(); + if (!paletteLookup[rgb] && $.inArray(rgb, selectionPalette) === -1) { + selectionPalette.push(rgb); + while(selectionPalette.length > maxSelectionSize) { + selectionPalette.shift(); + } + } + + if (localStorageKey && window.localStorage) { + try { + window.localStorage[localStorageKey] = selectionPalette.join(";"); + } + catch(e) { } + } + } + } + + function getUniqueSelectionPalette() { + var unique = []; + if (opts.showPalette) { + for (var i = 0; i < selectionPalette.length; i++) { + var rgb = tinycolor(selectionPalette[i]).toRgbString(); + + if (!paletteLookup[rgb]) { + unique.push(selectionPalette[i]); + } + } + } + + return unique.reverse().slice(0, opts.maxSelectionSize); + } + + function drawPalette() { + + var currentColor = get(); + + var html = $.map(paletteArray, function (palette, i) { + return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i, opts); + }); + + updateSelectionPaletteFromStorage(); + + if (selectionPalette) { + html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection", opts)); + } + + paletteContainer.html(html.join("")); + } + + function drawInitial() { + if (opts.showInitial) { + var initial = colorOnShow; + var current = get(); + initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial", opts)); + } + } + + function dragStart() { + if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) { + reflow(); + } + isDragging = true; + container.addClass(draggingClass); + shiftMovementDirection = null; + boundElement.trigger('dragstart.spectrum', [ get() ]); + } + + function dragStop() { + isDragging = false; + container.removeClass(draggingClass); + boundElement.trigger('dragstop.spectrum', [ get() ]); + } + + function setFromTextInput() { + + var value = textInput.val(); + + if ((value === null || value === "") && allowEmpty) { + set(null); + updateOriginalInput(true); + } + else { + var tiny = tinycolor(value); + if (tiny.isValid()) { + set(tiny); + updateOriginalInput(true); + } + else { + textInput.addClass("sp-validation-error"); + } + } + } + + function toggle() { + if (visible) { + hide(); + } + else { + show(); + } + } + + function show() { + var event = $.Event('beforeShow.spectrum'); + + if (visible) { + reflow(); + return; + } + + boundElement.trigger(event, [ get() ]); + + if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) { + return; + } + + hideAll(); + visible = true; + + $(doc).bind("keydown.spectrum", onkeydown); + $(doc).bind("click.spectrum", clickout); + $(window).bind("resize.spectrum", resize); + replacer.addClass("sp-active"); + container.removeClass("sp-hidden"); + + reflow(); + updateUI(); + + colorOnShow = get(); + + drawInitial(); + callbacks.show(colorOnShow); + boundElement.trigger('show.spectrum', [ colorOnShow ]); + } + + function onkeydown(e) { + // Close on ESC + if (e.keyCode === 27) { + hide(); + } + } + + function clickout(e) { + // Return on right click. + if (e.button == 2) { return; } + + // If a drag event was happening during the mouseup, don't hide + // on click. + if (isDragging) { return; } + + if (clickoutFiresChange) { + updateOriginalInput(true); + } + else { + revert(); + } + hide(); + } + + function hide() { + // Return if hiding is unnecessary + if (!visible || flat) { return; } + visible = false; + + $(doc).unbind("keydown.spectrum", onkeydown); + $(doc).unbind("click.spectrum", clickout); + $(window).unbind("resize.spectrum", resize); + + replacer.removeClass("sp-active"); + container.addClass("sp-hidden"); + + callbacks.hide(get()); + boundElement.trigger('hide.spectrum', [ get() ]); + } + + function revert() { + set(colorOnShow, true); + } + + function set(color, ignoreFormatChange) { + if (tinycolor.equals(color, get())) { + // Update UI just in case a validation error needs + // to be cleared. + updateUI(); + return; + } + + var newColor, newHsv; + if (!color && allowEmpty) { + isEmpty = true; + } else { + isEmpty = false; + newColor = tinycolor(color); + newHsv = newColor.toHsv(); + + currentHue = (newHsv.h % 360) / 360; + currentSaturation = newHsv.s; + currentValue = newHsv.v; + currentAlpha = newHsv.a; + } + updateUI(); + + if (newColor && newColor.isValid() && !ignoreFormatChange) { + currentPreferredFormat = opts.preferredFormat || newColor.getFormat(); + } + } + + function get(opts) { + opts = opts || { }; + + if (allowEmpty && isEmpty) { + return null; + } + + return tinycolor.fromRatio({ + h: currentHue, + s: currentSaturation, + v: currentValue, + a: Math.round(currentAlpha * 100) / 100 + }, { format: opts.format || currentPreferredFormat }); + } + + function isValid() { + return !textInput.hasClass("sp-validation-error"); + } + + function move() { + updateUI(); + + callbacks.move(get()); + boundElement.trigger('move.spectrum', [ get() ]); + } + + function updateUI() { + + textInput.removeClass("sp-validation-error"); + + updateHelperLocations(); + + // Update dragger background color (gradients take care of saturation and value). + var flatColor = tinycolor.fromRatio({ h: currentHue, s: 1, v: 1 }); + dragger.css("background-color", flatColor.toHexString()); + + // Get a format that alpha will be included in (hex and names ignore alpha) + var format = currentPreferredFormat; + if (currentAlpha < 1 && !(currentAlpha === 0 && format === "name")) { + if (format === "hex" || format === "hex3" || format === "hex6" || format === "name") { + format = "rgb"; + } + } + + var realColor = get({ format: format }), + displayColor = ''; + + //reset background info for preview element + previewElement.removeClass("sp-clear-display"); + previewElement.css('background-color', 'transparent'); + + if (!realColor && allowEmpty) { + // Update the replaced elements background with icon indicating no color selection + previewElement.addClass("sp-clear-display"); + } + else { + var realHex = realColor.toHexString(), + realRgb = realColor.toRgbString(); + + // Update the replaced elements background color (with actual selected color) + if (rgbaSupport || realColor.alpha === 1) { + previewElement.css("background-color", realRgb); + } + else { + previewElement.css("background-color", "transparent"); + previewElement.css("filter", realColor.toFilter()); + } + + if (opts.showAlpha) { + var rgb = realColor.toRgb(); + rgb.a = 0; + var realAlpha = tinycolor(rgb).toRgbString(); + var gradient = "linear-gradient(left, " + realAlpha + ", " + realHex + ")"; + + if (IE) { + alphaSliderInner.css("filter", tinycolor(realAlpha).toFilter({ gradientType: 1 }, realHex)); + } + else { + alphaSliderInner.css("background", "-webkit-" + gradient); + alphaSliderInner.css("background", "-moz-" + gradient); + alphaSliderInner.css("background", "-ms-" + gradient); + // Use current syntax gradient on unprefixed property. + alphaSliderInner.css("background", + "linear-gradient(to right, " + realAlpha + ", " + realHex + ")"); + } + } + + displayColor = realColor.toString(format); + } + + // Update the text entry input as it changes happen + if (opts.showInput) { + textInput.val(displayColor); + } + + if (opts.showPalette) { + drawPalette(); + } + + drawInitial(); + } + + function updateHelperLocations() { + var s = currentSaturation; + var v = currentValue; + + if(allowEmpty && isEmpty) { + //if selected color is empty, hide the helpers + alphaSlideHelper.hide(); + slideHelper.hide(); + dragHelper.hide(); + } + else { + //make sure helpers are visible + alphaSlideHelper.show(); + slideHelper.show(); + dragHelper.show(); + + // Where to show the little circle in that displays your current selected color + var dragX = s * dragWidth; + var dragY = dragHeight - (v * dragHeight); + dragX = Math.max( + -dragHelperHeight, + Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight) + ); + dragY = Math.max( + -dragHelperHeight, + Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight) + ); + dragHelper.css({ + "top": dragY + "px", + "left": dragX + "px" + }); + + var alphaX = currentAlpha * alphaWidth; + alphaSlideHelper.css({ + "left": (alphaX - (alphaSlideHelperWidth / 2)) + "px" + }); + + // Where to show the bar that displays your current selected hue + var slideY = (currentHue) * slideHeight; + slideHelper.css({ + "top": (slideY - slideHelperHeight) + "px" + }); + } + } + + function updateOriginalInput(fireCallback) { + var color = get(), + displayColor = '', + hasChanged = !tinycolor.equals(color, colorOnShow); + + if (color) { + displayColor = color.toString(currentPreferredFormat); + // Update the selection palette with the current color + addColorToSelectionPalette(color); + } + + if (isInput) { + boundElement.val(displayColor); + } + + if (fireCallback && hasChanged) { + callbacks.change(color); + boundElement.trigger('change', [ color ]); + } + } + + function reflow() { + if (!visible) { + return; // Calculations would be useless and wouldn't be reliable anyways + } + dragWidth = dragger.width(); + dragHeight = dragger.height(); + dragHelperHeight = dragHelper.height(); + slideWidth = slider.width(); + slideHeight = slider.height(); + slideHelperHeight = slideHelper.height(); + alphaWidth = alphaSlider.width(); + alphaSlideHelperWidth = alphaSlideHelper.width(); + + if (!flat) { + container.css("position", "absolute"); + if (opts.offset) { + container.offset(opts.offset); + } else { + container.offset(getOffset(container, offsetElement)); + } + } + + updateHelperLocations(); + + if (opts.showPalette) { + drawPalette(); + } + + boundElement.trigger('reflow.spectrum'); + } + + function destroy() { + boundElement.show(); + offsetElement.unbind("click.spectrum touchstart.spectrum"); + container.remove(); + replacer.remove(); + spectrums[spect.id] = null; + } + + function option(optionName, optionValue) { + if (optionName === undefined) { + return $.extend({}, opts); + } + if (optionValue === undefined) { + return opts[optionName]; + } + + opts[optionName] = optionValue; + + if (optionName === "preferredFormat") { + currentPreferredFormat = opts.preferredFormat; + } + applyOptions(); + } + + function enable() { + disabled = false; + boundElement.attr("disabled", false); + offsetElement.removeClass("sp-disabled"); + } + + function disable() { + hide(); + disabled = true; + boundElement.attr("disabled", true); + offsetElement.addClass("sp-disabled"); + } + + function setOffset(coord) { + opts.offset = coord; + reflow(); + } + + initialize(); + + var spect = { + show: show, + hide: hide, + toggle: toggle, + reflow: reflow, + option: option, + enable: enable, + disable: disable, + offset: setOffset, + set: function (c) { + set(c); + updateOriginalInput(); + }, + get: get, + destroy: destroy, + container: container + }; + + spect.id = spectrums.push(spect) - 1; + + return spect; + } + + /** + * checkOffset - get the offset below/above and left/right element depending on screen position + * Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js + */ + function getOffset(picker, input) { + var extraY = 0; + var dpWidth = picker.outerWidth(); + var dpHeight = picker.outerHeight(); + var inputHeight = input.outerHeight(); + var doc = picker[0].ownerDocument; + var docElem = doc.documentElement; + var viewWidth = docElem.clientWidth + $(doc).scrollLeft(); + var viewHeight = docElem.clientHeight + $(doc).scrollTop(); + var offset = input.offset(); + offset.top += inputHeight; + + offset.left -= + Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? + Math.abs(offset.left + dpWidth - viewWidth) : 0); + + offset.top -= + Math.min(offset.top, ((offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? + Math.abs(dpHeight + inputHeight - extraY) : extraY)); + + return offset; + } + + /** + * noop - do nothing + */ + function noop() { + + } + + /** + * stopPropagation - makes the code only doing this a little easier to read in line + */ + function stopPropagation(e) { + e.stopPropagation(); + } + + /** + * Create a function bound to a given object + * Thanks to underscore.js + */ + function bind(func, obj) { + var slice = Array.prototype.slice; + var args = slice.call(arguments, 2); + return function () { + return func.apply(obj, args.concat(slice.call(arguments))); + }; + } + + /** + * Lightweight drag helper. Handles containment within the element, so that + * when dragging, the x is within [0,element.width] and y is within [0,element.height] + */ + function draggable(element, onmove, onstart, onstop) { + onmove = onmove || function () { }; + onstart = onstart || function () { }; + onstop = onstop || function () { }; + var doc = document; + var dragging = false; + var offset = {}; + var maxHeight = 0; + var maxWidth = 0; + var hasTouch = ('ontouchstart' in window); + + var duringDragEvents = {}; + duringDragEvents["selectstart"] = prevent; + duringDragEvents["dragstart"] = prevent; + duringDragEvents["touchmove mousemove"] = move; + duringDragEvents["touchend mouseup"] = stop; + + function prevent(e) { + if (e.stopPropagation) { + e.stopPropagation(); + } + if (e.preventDefault) { + e.preventDefault(); + } + e.returnValue = false; + } + + function move(e) { + if (dragging) { + // Mouseup happened outside of window + if (IE && doc.documentMode < 9 && !e.button) { + return stop(); + } + + var t0 = e.originalEvent && e.originalEvent.touches && e.originalEvent.touches[0]; + var pageX = t0 && t0.pageX || e.pageX; + var pageY = t0 && t0.pageY || e.pageY; + + var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth)); + var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight)); + + if (hasTouch) { + // Stop scrolling in iOS + prevent(e); + } + + onmove.apply(element, [dragX, dragY, e]); + } + } + + function start(e) { + var rightclick = (e.which) ? (e.which == 3) : (e.button == 2); + + if (!rightclick && !dragging) { + if (onstart.apply(element, arguments) !== false) { + dragging = true; + maxHeight = $(element).height(); + maxWidth = $(element).width(); + offset = $(element).offset(); + + $(doc).bind(duringDragEvents); + $(doc.body).addClass("sp-dragging"); + + move(e); + + prevent(e); + } + } + } + + function stop() { + if (dragging) { + $(doc).unbind(duringDragEvents); + $(doc.body).removeClass("sp-dragging"); + + // Wait a tick before notifying observers to allow the click event + // to fire in Chrome. + setTimeout(function() { + onstop.apply(element, arguments); + }, 0); + } + dragging = false; + } + + $(element).bind("touchstart mousedown", start); + } + + function throttle(func, wait, debounce) { + var timeout; + return function () { + var context = this, args = arguments; + var throttler = function () { + timeout = null; + func.apply(context, args); + }; + if (debounce) clearTimeout(timeout); + if (debounce || !timeout) timeout = setTimeout(throttler, wait); + }; + } + + function inputTypeColorSupport() { + return $.fn.spectrum.inputTypeColorSupport(); + } + + /** + * Define a jQuery plugin + */ + var dataID = "spectrum.id"; + $.fn.spectrum = function (opts, extra) { + + if (typeof opts == "string") { + + var returnValue = this; + var args = Array.prototype.slice.call( arguments, 1 ); + + this.each(function () { + var spect = spectrums[$(this).data(dataID)]; + if (spect) { + var method = spect[opts]; + if (!method) { + throw new Error( "Spectrum: no such method: '" + opts + "'" ); + } + + if (opts == "get") { + returnValue = spect.get(); + } + else if (opts == "container") { + returnValue = spect.container; + } + else if (opts == "option") { + returnValue = spect.option.apply(spect, args); + } + else if (opts == "destroy") { + spect.destroy(); + $(this).removeData(dataID); + } + else { + method.apply(spect, args); + } + } + }); + + return returnValue; + } + + // Initializing a new instance of spectrum + return this.spectrum("destroy").each(function () { + var options = $.extend({}, opts, $(this).data()); + var spect = spectrum(this, options); + $(this).data(dataID, spect.id); + }); + }; + + $.fn.spectrum.load = true; + $.fn.spectrum.loadOpts = {}; + $.fn.spectrum.draggable = draggable; + $.fn.spectrum.defaults = defaultOpts; + $.fn.spectrum.inputTypeColorSupport = function inputTypeColorSupport() { + if (typeof inputTypeColorSupport._cachedResult === "undefined") { + var colorInput = $("")[0]; // if color element is supported, value will default to not null + inputTypeColorSupport._cachedResult = colorInput.type === "color" && colorInput.value !== ""; + } + return inputTypeColorSupport._cachedResult; + }; + + $.spectrum = { }; + $.spectrum.localization = { }; + $.spectrum.palettes = { }; + + $.fn.spectrum.processNativeColorInputs = function () { + var colorInputs = $("input[type=color]"); + if (colorInputs.length && !inputTypeColorSupport()) { + colorInputs.spectrum({ + preferredFormat: "hex6" + }); + } + }; + + // TinyColor v1.1.2 + // https://github.com/bgrins/TinyColor + // Brian Grinstead, MIT License + + (function() { + + var trimLeft = /^[\s,#]+/, + trimRight = /\s+$/, + tinyCounter = 0, + math = Math, + mathRound = math.round, + mathMin = math.min, + mathMax = math.max, + mathRandom = math.random; + + var tinycolor = function(color, opts) { + + color = (color) ? color : ''; + opts = opts || { }; + + // If input is already a tinycolor, return itself + if (color instanceof tinycolor) { + return color; + } + // If we are called as a function, call using new instead + if (!(this instanceof tinycolor)) { + return new tinycolor(color, opts); + } + + var rgb = inputToRGB(color); + this._originalInput = color, + this._r = rgb.r, + this._g = rgb.g, + this._b = rgb.b, + this._a = rgb.a, + this._roundA = mathRound(100*this._a) / 100, + this._format = opts.format || rgb.format; + this._gradientType = opts.gradientType; + + // Don't let the range of [0,255] come back in [0,1]. + // Potentially lose a little bit of precision here, but will fix issues where + // .5 gets interpreted as half of the total, instead of half of 1 + // If it was supposed to be 128, this was already taken care of by `inputToRgb` + if (this._r < 1) { this._r = mathRound(this._r); } + if (this._g < 1) { this._g = mathRound(this._g); } + if (this._b < 1) { this._b = mathRound(this._b); } + + this._ok = rgb.ok; + this._tc_id = tinyCounter++; + }; + + tinycolor.prototype = { + isDark: function() { + return this.getBrightness() < 128; + }, + isLight: function() { + return !this.isDark(); + }, + isValid: function() { + return this._ok; + }, + getOriginalInput: function() { + return this._originalInput; + }, + getFormat: function() { + return this._format; + }, + getAlpha: function() { + return this._a; + }, + getBrightness: function() { + var rgb = this.toRgb(); + return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000; + }, + setAlpha: function(value) { + this._a = boundAlpha(value); + this._roundA = mathRound(100*this._a) / 100; + return this; + }, + toHsv: function() { + var hsv = rgbToHsv(this._r, this._g, this._b); + return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a }; + }, + toHsvString: function() { + var hsv = rgbToHsv(this._r, this._g, this._b); + var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100); + return (this._a == 1) ? + "hsv(" + h + ", " + s + "%, " + v + "%)" : + "hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")"; + }, + toHsl: function() { + var hsl = rgbToHsl(this._r, this._g, this._b); + return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a }; + }, + toHslString: function() { + var hsl = rgbToHsl(this._r, this._g, this._b); + var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100); + return (this._a == 1) ? + "hsl(" + h + ", " + s + "%, " + l + "%)" : + "hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")"; + }, + toHex: function(allow3Char) { + return rgbToHex(this._r, this._g, this._b, allow3Char); + }, + toHexString: function(allow3Char) { + return '#' + this.toHex(allow3Char); + }, + toHex8: function() { + return rgbaToHex(this._r, this._g, this._b, this._a); + }, + toHex8String: function() { + return '#' + this.toHex8(); + }, + toRgb: function() { + return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a }; + }, + toRgbString: function() { + return (this._a == 1) ? + "rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" : + "rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")"; + }, + toPercentageRgb: function() { + return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a }; + }, + toPercentageRgbString: function() { + return (this._a == 1) ? + "rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" : + "rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")"; + }, + toName: function() { + if (this._a === 0) { + return "transparent"; + } + + if (this._a < 1) { + return false; + } + + return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false; + }, + toFilter: function(secondColor) { + var hex8String = '#' + rgbaToHex(this._r, this._g, this._b, this._a); + var secondHex8String = hex8String; + var gradientType = this._gradientType ? "GradientType = 1, " : ""; + + if (secondColor) { + var s = tinycolor(secondColor); + secondHex8String = s.toHex8String(); + } + + return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")"; + }, + toString: function(format) { + var formatSet = !!format; + format = format || this._format; + + var formattedString = false; + var hasAlpha = this._a < 1 && this._a >= 0; + var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "name"); + + if (needsAlphaFormat) { + // Special case for "transparent", all other non-alpha formats + // will return rgba when there is transparency. + if (format === "name" && this._a === 0) { + return this.toName(); + } + return this.toRgbString(); + } + if (format === "rgb") { + formattedString = this.toRgbString(); + } + if (format === "prgb") { + formattedString = this.toPercentageRgbString(); + } + if (format === "hex" || format === "hex6") { + formattedString = this.toHexString(); + } + if (format === "hex3") { + formattedString = this.toHexString(true); + } + if (format === "hex8") { + formattedString = this.toHex8String(); + } + if (format === "name") { + formattedString = this.toName(); + } + if (format === "hsl") { + formattedString = this.toHslString(); + } + if (format === "hsv") { + formattedString = this.toHsvString(); + } + + return formattedString || this.toHexString(); + }, + + _applyModification: function(fn, args) { + var color = fn.apply(null, [this].concat([].slice.call(args))); + this._r = color._r; + this._g = color._g; + this._b = color._b; + this.setAlpha(color._a); + return this; + }, + lighten: function() { + return this._applyModification(lighten, arguments); + }, + brighten: function() { + return this._applyModification(brighten, arguments); + }, + darken: function() { + return this._applyModification(darken, arguments); + }, + desaturate: function() { + return this._applyModification(desaturate, arguments); + }, + saturate: function() { + return this._applyModification(saturate, arguments); + }, + greyscale: function() { + return this._applyModification(greyscale, arguments); + }, + spin: function() { + return this._applyModification(spin, arguments); + }, + + _applyCombination: function(fn, args) { + return fn.apply(null, [this].concat([].slice.call(args))); + }, + analogous: function() { + return this._applyCombination(analogous, arguments); + }, + complement: function() { + return this._applyCombination(complement, arguments); + }, + monochromatic: function() { + return this._applyCombination(monochromatic, arguments); + }, + splitcomplement: function() { + return this._applyCombination(splitcomplement, arguments); + }, + triad: function() { + return this._applyCombination(triad, arguments); + }, + tetrad: function() { + return this._applyCombination(tetrad, arguments); + } + }; + + // If input is an object, force 1 into "1.0" to handle ratios properly + // String input requires "1.0" as input, so 1 will be treated as 1 + tinycolor.fromRatio = function(color, opts) { + if (typeof color == "object") { + var newColor = {}; + for (var i in color) { + if (color.hasOwnProperty(i)) { + if (i === "a") { + newColor[i] = color[i]; + } + else { + newColor[i] = convertToPercentage(color[i]); + } + } + } + color = newColor; + } + + return tinycolor(color, opts); + }; + + // Given a string or object, convert that input to RGB + // Possible string inputs: + // + // "red" + // "#f00" or "f00" + // "#ff0000" or "ff0000" + // "#ff000000" or "ff000000" + // "rgb 255 0 0" or "rgb (255, 0, 0)" + // "rgb 1.0 0 0" or "rgb (1, 0, 0)" + // "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1" + // "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1" + // "hsl(0, 100%, 50%)" or "hsl 0 100% 50%" + // "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1" + // "hsv(0, 100%, 100%)" or "hsv 0 100% 100%" + // + function inputToRGB(color) { + + var rgb = { r: 0, g: 0, b: 0 }; + var a = 1; + var ok = false; + var format = false; + + if (typeof color == "string") { + color = stringInputToObject(color); + } + + if (typeof color == "object") { + if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) { + rgb = rgbToRgb(color.r, color.g, color.b); + ok = true; + format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb"; + } + else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) { + color.s = convertToPercentage(color.s); + color.v = convertToPercentage(color.v); + rgb = hsvToRgb(color.h, color.s, color.v); + ok = true; + format = "hsv"; + } + else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) { + color.s = convertToPercentage(color.s); + color.l = convertToPercentage(color.l); + rgb = hslToRgb(color.h, color.s, color.l); + ok = true; + format = "hsl"; + } + + if (color.hasOwnProperty("a")) { + a = color.a; + } + } + + a = boundAlpha(a); + + return { + ok: ok, + format: color.format || format, + r: mathMin(255, mathMax(rgb.r, 0)), + g: mathMin(255, mathMax(rgb.g, 0)), + b: mathMin(255, mathMax(rgb.b, 0)), + a: a + }; + } + + + // Conversion Functions + // -------------------- + + // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from: + // + + // `rgbToRgb` + // Handle bounds / percentage checking to conform to CSS color spec + // + // *Assumes:* r, g, b in [0, 255] or [0, 1] + // *Returns:* { r, g, b } in [0, 255] + function rgbToRgb(r, g, b){ + return { + r: bound01(r, 255) * 255, + g: bound01(g, 255) * 255, + b: bound01(b, 255) * 255 + }; + } + + // `rgbToHsl` + // Converts an RGB color value to HSL. + // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1] + // *Returns:* { h, s, l } in [0,1] + function rgbToHsl(r, g, b) { + + r = bound01(r, 255); + g = bound01(g, 255); + b = bound01(b, 255); + + var max = mathMax(r, g, b), min = mathMin(r, g, b); + var h, s, l = (max + min) / 2; + + if(max == min) { + h = s = 0; // achromatic + } + else { + var d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch(max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + + h /= 6; + } + + return { h: h, s: s, l: l }; + } + + // `hslToRgb` + // Converts an HSL color value to RGB. + // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100] + // *Returns:* { r, g, b } in the set [0, 255] + function hslToRgb(h, s, l) { + var r, g, b; + + h = bound01(h, 360); + s = bound01(s, 100); + l = bound01(l, 100); + + function hue2rgb(p, q, t) { + if(t < 0) t += 1; + if(t > 1) t -= 1; + if(t < 1/6) return p + (q - p) * 6 * t; + if(t < 1/2) return q; + if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; + return p; + } + + if(s === 0) { + r = g = b = l; // achromatic + } + else { + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = hue2rgb(p, q, h + 1/3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1/3); + } + + return { r: r * 255, g: g * 255, b: b * 255 }; + } + + // `rgbToHsv` + // Converts an RGB color value to HSV + // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1] + // *Returns:* { h, s, v } in [0,1] + function rgbToHsv(r, g, b) { + + r = bound01(r, 255); + g = bound01(g, 255); + b = bound01(b, 255); + + var max = mathMax(r, g, b), min = mathMin(r, g, b); + var h, s, v = max; + + var d = max - min; + s = max === 0 ? 0 : d / max; + + if(max == min) { + h = 0; // achromatic + } + else { + switch(max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } + return { h: h, s: s, v: v }; + } + + // `hsvToRgb` + // Converts an HSV color value to RGB. + // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100] + // *Returns:* { r, g, b } in the set [0, 255] + function hsvToRgb(h, s, v) { + + h = bound01(h, 360) * 6; + s = bound01(s, 100); + v = bound01(v, 100); + + var i = math.floor(h), + f = h - i, + p = v * (1 - s), + q = v * (1 - f * s), + t = v * (1 - (1 - f) * s), + mod = i % 6, + r = [v, q, p, p, t, v][mod], + g = [t, v, v, q, p, p][mod], + b = [p, p, t, v, v, q][mod]; + + return { r: r * 255, g: g * 255, b: b * 255 }; + } + + // `rgbToHex` + // Converts an RGB color to hex + // Assumes r, g, and b are contained in the set [0, 255] + // Returns a 3 or 6 character hex + function rgbToHex(r, g, b, allow3Char) { + + var hex = [ + pad2(mathRound(r).toString(16)), + pad2(mathRound(g).toString(16)), + pad2(mathRound(b).toString(16)) + ]; + + // Return a 3 character hex if possible + if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) { + return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0); + } + + return hex.join(""); + } + // `rgbaToHex` + // Converts an RGBA color plus alpha transparency to hex + // Assumes r, g, b and a are contained in the set [0, 255] + // Returns an 8 character hex + function rgbaToHex(r, g, b, a) { + + var hex = [ + pad2(convertDecimalToHex(a)), + pad2(mathRound(r).toString(16)), + pad2(mathRound(g).toString(16)), + pad2(mathRound(b).toString(16)) + ]; + + return hex.join(""); + } + + // `equals` + // Can be called with any tinycolor input + tinycolor.equals = function (color1, color2) { + if (!color1 || !color2) { return false; } + return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString(); + }; + tinycolor.random = function() { + return tinycolor.fromRatio({ + r: mathRandom(), + g: mathRandom(), + b: mathRandom() + }); + }; + + + // Modification Functions + // ---------------------- + // Thanks to less.js for some of the basics here + // + + function desaturate(color, amount) { + amount = (amount === 0) ? 0 : (amount || 10); + var hsl = tinycolor(color).toHsl(); + hsl.s -= amount / 100; + hsl.s = clamp01(hsl.s); + return tinycolor(hsl); + } + + function saturate(color, amount) { + amount = (amount === 0) ? 0 : (amount || 10); + var hsl = tinycolor(color).toHsl(); + hsl.s += amount / 100; + hsl.s = clamp01(hsl.s); + return tinycolor(hsl); + } + + function greyscale(color) { + return tinycolor(color).desaturate(100); + } + + function lighten (color, amount) { + amount = (amount === 0) ? 0 : (amount || 10); + var hsl = tinycolor(color).toHsl(); + hsl.l += amount / 100; + hsl.l = clamp01(hsl.l); + return tinycolor(hsl); + } + + function brighten(color, amount) { + amount = (amount === 0) ? 0 : (amount || 10); + var rgb = tinycolor(color).toRgb(); + rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100)))); + rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100)))); + rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100)))); + return tinycolor(rgb); + } + + function darken (color, amount) { + amount = (amount === 0) ? 0 : (amount || 10); + var hsl = tinycolor(color).toHsl(); + hsl.l -= amount / 100; + hsl.l = clamp01(hsl.l); + return tinycolor(hsl); + } + + // Spin takes a positive or negative amount within [-360, 360] indicating the change of hue. + // Values outside of this range will be wrapped into this range. + function spin(color, amount) { + var hsl = tinycolor(color).toHsl(); + var hue = (mathRound(hsl.h) + amount) % 360; + hsl.h = hue < 0 ? 360 + hue : hue; + return tinycolor(hsl); + } + + // Combination Functions + // --------------------- + // Thanks to jQuery xColor for some of the ideas behind these + // + + function complement(color) { + var hsl = tinycolor(color).toHsl(); + hsl.h = (hsl.h + 180) % 360; + return tinycolor(hsl); + } + + function triad(color) { + var hsl = tinycolor(color).toHsl(); + var h = hsl.h; + return [ + tinycolor(color), + tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }), + tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l }) + ]; + } + + function tetrad(color) { + var hsl = tinycolor(color).toHsl(); + var h = hsl.h; + return [ + tinycolor(color), + tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }), + tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }), + tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l }) + ]; + } + + function splitcomplement(color) { + var hsl = tinycolor(color).toHsl(); + var h = hsl.h; + return [ + tinycolor(color), + tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}), + tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l}) + ]; + } + + function analogous(color, results, slices) { + results = results || 6; + slices = slices || 30; + + var hsl = tinycolor(color).toHsl(); + var part = 360 / slices; + var ret = [tinycolor(color)]; + + for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) { + hsl.h = (hsl.h + part) % 360; + ret.push(tinycolor(hsl)); + } + return ret; + } + + function monochromatic(color, results) { + results = results || 6; + var hsv = tinycolor(color).toHsv(); + var h = hsv.h, s = hsv.s, v = hsv.v; + var ret = []; + var modification = 1 / results; + + while (results--) { + ret.push(tinycolor({ h: h, s: s, v: v})); + v = (v + modification) % 1; + } + + return ret; + } + + // Utility Functions + // --------------------- + + tinycolor.mix = function(color1, color2, amount) { + amount = (amount === 0) ? 0 : (amount || 50); + + var rgb1 = tinycolor(color1).toRgb(); + var rgb2 = tinycolor(color2).toRgb(); + + var p = amount / 100; + var w = p * 2 - 1; + var a = rgb2.a - rgb1.a; + + var w1; + + if (w * a == -1) { + w1 = w; + } else { + w1 = (w + a) / (1 + w * a); + } + + w1 = (w1 + 1) / 2; + + var w2 = 1 - w1; + + var rgba = { + r: rgb2.r * w1 + rgb1.r * w2, + g: rgb2.g * w1 + rgb1.g * w2, + b: rgb2.b * w1 + rgb1.b * w2, + a: rgb2.a * p + rgb1.a * (1 - p) + }; + + return tinycolor(rgba); + }; + + + // Readability Functions + // --------------------- + // + + // `readability` + // Analyze the 2 colors and returns an object with the following properties: + // `brightness`: difference in brightness between the two colors + // `color`: difference in color/hue between the two colors + tinycolor.readability = function(color1, color2) { + var c1 = tinycolor(color1); + var c2 = tinycolor(color2); + var rgb1 = c1.toRgb(); + var rgb2 = c2.toRgb(); + var brightnessA = c1.getBrightness(); + var brightnessB = c2.getBrightness(); + var colorDiff = ( + Math.max(rgb1.r, rgb2.r) - Math.min(rgb1.r, rgb2.r) + + Math.max(rgb1.g, rgb2.g) - Math.min(rgb1.g, rgb2.g) + + Math.max(rgb1.b, rgb2.b) - Math.min(rgb1.b, rgb2.b) + ); + + return { + brightness: Math.abs(brightnessA - brightnessB), + color: colorDiff + }; + }; + + // `readable` + // http://www.w3.org/TR/AERT#color-contrast + // Ensure that foreground and background color combinations provide sufficient contrast. + // *Example* + // tinycolor.isReadable("#000", "#111") => false + tinycolor.isReadable = function(color1, color2) { + var readability = tinycolor.readability(color1, color2); + return readability.brightness > 125 && readability.color > 500; + }; + + // `mostReadable` + // Given a base color and a list of possible foreground or background + // colors for that base, returns the most readable color. + // *Example* + // tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000" + tinycolor.mostReadable = function(baseColor, colorList) { + var bestColor = null; + var bestScore = 0; + var bestIsReadable = false; + for (var i=0; i < colorList.length; i++) { + + // We normalize both around the "acceptable" breaking point, + // but rank brightness constrast higher than hue. + + var readability = tinycolor.readability(baseColor, colorList[i]); + var readable = readability.brightness > 125 && readability.color > 500; + var score = 3 * (readability.brightness / 125) + (readability.color / 500); + + if ((readable && ! bestIsReadable) || + (readable && bestIsReadable && score > bestScore) || + ((! readable) && (! bestIsReadable) && score > bestScore)) { + bestIsReadable = readable; + bestScore = score; + bestColor = tinycolor(colorList[i]); + } + } + return bestColor; + }; + + + // Big List of Colors + // ------------------ + // + var names = tinycolor.names = { + aliceblue: "f0f8ff", + antiquewhite: "faebd7", + aqua: "0ff", + aquamarine: "7fffd4", + azure: "f0ffff", + beige: "f5f5dc", + bisque: "ffe4c4", + black: "000", + blanchedalmond: "ffebcd", + blue: "00f", + blueviolet: "8a2be2", + brown: "a52a2a", + burlywood: "deb887", + burntsienna: "ea7e5d", + cadetblue: "5f9ea0", + chartreuse: "7fff00", + chocolate: "d2691e", + coral: "ff7f50", + cornflowerblue: "6495ed", + cornsilk: "fff8dc", + crimson: "dc143c", + cyan: "0ff", + darkblue: "00008b", + darkcyan: "008b8b", + darkgoldenrod: "b8860b", + darkgray: "a9a9a9", + darkgreen: "006400", + darkgrey: "a9a9a9", + darkkhaki: "bdb76b", + darkmagenta: "8b008b", + darkolivegreen: "556b2f", + darkorange: "ff8c00", + darkorchid: "9932cc", + darkred: "8b0000", + darksalmon: "e9967a", + darkseagreen: "8fbc8f", + darkslateblue: "483d8b", + darkslategray: "2f4f4f", + darkslategrey: "2f4f4f", + darkturquoise: "00ced1", + darkviolet: "9400d3", + deeppink: "ff1493", + deepskyblue: "00bfff", + dimgray: "696969", + dimgrey: "696969", + dodgerblue: "1e90ff", + firebrick: "b22222", + floralwhite: "fffaf0", + forestgreen: "228b22", + fuchsia: "f0f", + gainsboro: "dcdcdc", + ghostwhite: "f8f8ff", + gold: "ffd700", + goldenrod: "daa520", + gray: "808080", + green: "008000", + greenyellow: "adff2f", + grey: "808080", + honeydew: "f0fff0", + hotpink: "ff69b4", + indianred: "cd5c5c", + indigo: "4b0082", + ivory: "fffff0", + khaki: "f0e68c", + lavender: "e6e6fa", + lavenderblush: "fff0f5", + lawngreen: "7cfc00", + lemonchiffon: "fffacd", + lightblue: "add8e6", + lightcoral: "f08080", + lightcyan: "e0ffff", + lightgoldenrodyellow: "fafad2", + lightgray: "d3d3d3", + lightgreen: "90ee90", + lightgrey: "d3d3d3", + lightpink: "ffb6c1", + lightsalmon: "ffa07a", + lightseagreen: "20b2aa", + lightskyblue: "87cefa", + lightslategray: "789", + lightslategrey: "789", + lightsteelblue: "b0c4de", + lightyellow: "ffffe0", + lime: "0f0", + limegreen: "32cd32", + linen: "faf0e6", + magenta: "f0f", + maroon: "800000", + mediumaquamarine: "66cdaa", + mediumblue: "0000cd", + mediumorchid: "ba55d3", + mediumpurple: "9370db", + mediumseagreen: "3cb371", + mediumslateblue: "7b68ee", + mediumspringgreen: "00fa9a", + mediumturquoise: "48d1cc", + mediumvioletred: "c71585", + midnightblue: "191970", + mintcream: "f5fffa", + mistyrose: "ffe4e1", + moccasin: "ffe4b5", + navajowhite: "ffdead", + navy: "000080", + oldlace: "fdf5e6", + olive: "808000", + olivedrab: "6b8e23", + orange: "ffa500", + orangered: "ff4500", + orchid: "da70d6", + palegoldenrod: "eee8aa", + palegreen: "98fb98", + paleturquoise: "afeeee", + palevioletred: "db7093", + papayawhip: "ffefd5", + peachpuff: "ffdab9", + peru: "cd853f", + pink: "ffc0cb", + plum: "dda0dd", + powderblue: "b0e0e6", + purple: "800080", + rebeccapurple: "663399", + red: "f00", + rosybrown: "bc8f8f", + royalblue: "4169e1", + saddlebrown: "8b4513", + salmon: "fa8072", + sandybrown: "f4a460", + seagreen: "2e8b57", + seashell: "fff5ee", + sienna: "a0522d", + silver: "c0c0c0", + skyblue: "87ceeb", + slateblue: "6a5acd", + slategray: "708090", + slategrey: "708090", + snow: "fffafa", + springgreen: "00ff7f", + steelblue: "4682b4", + tan: "d2b48c", + teal: "008080", + thistle: "d8bfd8", + tomato: "ff6347", + turquoise: "40e0d0", + violet: "ee82ee", + wheat: "f5deb3", + white: "fff", + whitesmoke: "f5f5f5", + yellow: "ff0", + yellowgreen: "9acd32" + }; + + // Make it easy to access colors via `hexNames[hex]` + var hexNames = tinycolor.hexNames = flip(names); + + + // Utilities + // --------- + + // `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }` + function flip(o) { + var flipped = { }; + for (var i in o) { + if (o.hasOwnProperty(i)) { + flipped[o[i]] = i; + } + } + return flipped; + } + + // Return a valid alpha value [0,1] with all invalid values being set to 1 + function boundAlpha(a) { + a = parseFloat(a); + + if (isNaN(a) || a < 0 || a > 1) { + a = 1; + } + + return a; + } + + // Take input from [0, n] and return it as [0, 1] + function bound01(n, max) { + if (isOnePointZero(n)) { n = "100%"; } + + var processPercent = isPercentage(n); + n = mathMin(max, mathMax(0, parseFloat(n))); + + // Automatically convert percentage into number + if (processPercent) { + n = parseInt(n * max, 10) / 100; + } + + // Handle floating point rounding errors + if ((math.abs(n - max) < 0.000001)) { + return 1; + } + + // Convert into [0, 1] range if it isn't already + return (n % max) / parseFloat(max); + } + + // Force a number between 0 and 1 + function clamp01(val) { + return mathMin(1, mathMax(0, val)); + } + + // Parse a base-16 hex value into a base-10 integer + function parseIntFromHex(val) { + return parseInt(val, 16); + } + + // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1 + // + function isOnePointZero(n) { + return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1; + } + + // Check to see if string passed in is a percentage + function isPercentage(n) { + return typeof n === "string" && n.indexOf('%') != -1; + } + + // Force a hex value to have 2 characters + function pad2(c) { + return c.length == 1 ? '0' + c : '' + c; + } + + // Replace a decimal with it's percentage value + function convertToPercentage(n) { + if (n <= 1) { + n = (n * 100) + "%"; + } + + return n; + } + + // Converts a decimal to a hex value + function convertDecimalToHex(d) { + return Math.round(parseFloat(d) * 255).toString(16); + } + // Converts a hex value to a decimal + function convertHexToDecimal(h) { + return (parseIntFromHex(h) / 255); + } + + var matchers = (function() { + + // + var CSS_INTEGER = "[-\\+]?\\d+%?"; + + // + var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?"; + + // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome. + var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")"; + + // Actual matching. + // Parentheses and commas are optional, but not required. + // Whitespace can take the place of commas or opening paren + var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; + var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; + + return { + rgb: new RegExp("rgb" + PERMISSIVE_MATCH3), + rgba: new RegExp("rgba" + PERMISSIVE_MATCH4), + hsl: new RegExp("hsl" + PERMISSIVE_MATCH3), + hsla: new RegExp("hsla" + PERMISSIVE_MATCH4), + hsv: new RegExp("hsv" + PERMISSIVE_MATCH3), + hsva: new RegExp("hsva" + PERMISSIVE_MATCH4), + hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, + hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/, + hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/ + }; + })(); + + // `stringInputToObject` + // Permissive string parsing. Take in a number of formats, and output an object + // based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}` + function stringInputToObject(color) { + + color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase(); + var named = false; + if (names[color]) { + color = names[color]; + named = true; + } + else if (color == 'transparent') { + return { r: 0, g: 0, b: 0, a: 0, format: "name" }; + } + + // Try to match string input using regular expressions. + // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360] + // Just return an object and let the conversion functions handle that. + // This way the result will be the same whether the tinycolor is initialized with string or object. + var match; + if ((match = matchers.rgb.exec(color))) { + return { r: match[1], g: match[2], b: match[3] }; + } + if ((match = matchers.rgba.exec(color))) { + return { r: match[1], g: match[2], b: match[3], a: match[4] }; + } + if ((match = matchers.hsl.exec(color))) { + return { h: match[1], s: match[2], l: match[3] }; + } + if ((match = matchers.hsla.exec(color))) { + return { h: match[1], s: match[2], l: match[3], a: match[4] }; + } + if ((match = matchers.hsv.exec(color))) { + return { h: match[1], s: match[2], v: match[3] }; + } + if ((match = matchers.hsva.exec(color))) { + return { h: match[1], s: match[2], v: match[3], a: match[4] }; + } + if ((match = matchers.hex8.exec(color))) { + return { + a: convertHexToDecimal(match[1]), + r: parseIntFromHex(match[2]), + g: parseIntFromHex(match[3]), + b: parseIntFromHex(match[4]), + format: named ? "name" : "hex8" + }; + } + if ((match = matchers.hex6.exec(color))) { + return { + r: parseIntFromHex(match[1]), + g: parseIntFromHex(match[2]), + b: parseIntFromHex(match[3]), + format: named ? "name" : "hex" + }; + } + if ((match = matchers.hex3.exec(color))) { + return { + r: parseIntFromHex(match[1] + '' + match[1]), + g: parseIntFromHex(match[2] + '' + match[2]), + b: parseIntFromHex(match[3] + '' + match[3]), + format: named ? "name" : "hex" + }; + } + + return false; + } + + window.tinycolor = tinycolor; + })(); + + $(function () { + if ($.fn.spectrum.load) { + $.fn.spectrum.processNativeColorInputs(); + } + }); + +}); From e1201963469a32f6a31387def99f3bdab05ae75d Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Mon, 26 Mar 2018 15:52:19 -0500 Subject: [PATCH 239/668] MAGETWO-89292: Implement SDL from prototype - remove test for Converter class --- .../GraphQl/Config/ConverterTest.php | 38 ----- .../GraphQl/_files/input_graphql.xml | 24 ---- .../GraphQl/_files/output_graphql.php | 134 ------------------ 3 files changed, 196 deletions(-) delete mode 100644 dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/ConverterTest.php delete mode 100644 dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/input_graphql.xml delete mode 100644 dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/output_graphql.php diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/ConverterTest.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/ConverterTest.php deleted file mode 100644 index b2760c9cb7c5e..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/ConverterTest.php +++ /dev/null @@ -1,38 +0,0 @@ -graphQlConverter = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() - ->create(\Magento\Framework\GraphQl\Config\Converter::class); - } - - /** - * @return void - */ - public function testConvert() - { - $this->source= new \DOMDocument(); - $this->source->load(__DIR__ . '../../_files/input_graphql.xml'); - $actualOutput = $this->graphQlConverter->convert($this->source); - $expectedResult = require __DIR__ . '../../_files/output_graphql.php'; - $this->assertEquals($expectedResult[0], $actualOutput); - } -} diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/input_graphql.xml b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/input_graphql.xml deleted file mode 100644 index d5aed3d828b65..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/input_graphql.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/output_graphql.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/output_graphql.php deleted file mode 100644 index c9707146152c2..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/output_graphql.php +++ /dev/null @@ -1,134 +0,0 @@ - - [ - "name" => "Query", - "type" => "graphql_type", - "fields" => - [ - "customAttributeMetadata" => - [ - "name" => "customAttributeMetadata", - "type" => "CustomAttributeMetadata", - "required" => false, - "resolver" => "Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata", - "arguments" => - [ - "attributes" => - [ - "type" => "ObjectArrayArgument", - "name" => "attributes", - "itemType" => "AttributeInput", - "itemsRequired" => "true", - "required" => "true" - ] - - ] - - ] - - ] - - ], - - "CustomAttributeMetadata" => - [ - "name" => "CustomAttributeMetadata", - "type" => "graphql_type", - "fields" => - [ - "items" => - [ - "name" => "items", - "type" => "ObjectArrayOutputField", - "required" => false, - "itemType" => "Attribute", - "arguments" => - [ - ] - - ] - - ] - - ], - - "Attribute" => - [ - "name" => "Attribute", - "type" => "graphql_type", - "fields" => - [ - "attribute_code" => - [ - "name" => "attribute_code", - "type" => "String", - "required" => "", - "arguments" => - [ - ] - - ], - - "entity_type" => - [ - "name" => "entity_type", - "type" => "String", - "required" => "", - "arguments" => - [ - ] - - ], - - "attribute_type" => - [ - "name" => "attribute_type", - "type" => "String", - "required" => "", - "arguments" => - [ - ] - - ] - - ] - - ], - "AttributeInput" => [ - "name" => "AttributeInput", - "type" => "graphql_input", - "fields" => [ - "attribute_code" => - [ - "name" => "attribute_code", - "type" => "String", - "required" => "", - "arguments" => - [ - ] - - ], - - "entity_type" => - [ - "name" => "entity_type", - "type" => "String", - "required" => "", - "arguments" => - [ - ] - - ] - - ] - - ] - - ] -]; From 60adf02a83a9948d84c8b72a580397ed19b9f8a1 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Mon, 26 Mar 2018 15:54:46 -0500 Subject: [PATCH 240/668] MAGETWO-89292: Implement SDL from prototype - renaming sdl filename --- .../BundleGraphQl/etc/{schema.graphql => schema.graphqls} | 0 .../CatalogGraphQl/etc/{schema.graphql => schema.graphqls} | 0 .../etc/{schema.graphql => schema.graphqls} | 0 .../etc/{schema.graphql => schema.graphqls} | 0 .../etc/{schema.graphql => schema.graphqls} | 0 .../CustomerGraphQl/etc/{schema.graphql => schema.graphqls} | 0 .../DownloadableGraphQl/etc/{schema.graphql => schema.graphqls} | 0 .../Magento/EavGraphQl/etc/{schema.graphql => schema.graphqls} | 0 .../Magento/GraphQl/etc/{schema.graphql => schema.graphqls} | 0 .../etc/{schema.graphql => schema.graphqls} | 0 .../SwatchesGraphQl/etc/{schema.graphql => schema.graphqls} | 0 .../Magento/TaxGraphQl/etc/{schema.graphql => schema.graphqls} | 0 .../UrlRewriteGraphQl/etc/{schema.graphql => schema.graphqls} | 0 .../Magento/WeeeGraphQl/etc/{schema.graphql => schema.graphqls} | 0 lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php | 2 +- 15 files changed, 1 insertion(+), 1 deletion(-) rename app/code/Magento/BundleGraphQl/etc/{schema.graphql => schema.graphqls} (100%) rename app/code/Magento/CatalogGraphQl/etc/{schema.graphql => schema.graphqls} (100%) rename app/code/Magento/CatalogUrlRewriteGraphQl/etc/{schema.graphql => schema.graphqls} (100%) rename app/code/Magento/CmsUrlRewriteGraphQl/etc/{schema.graphql => schema.graphqls} (100%) rename app/code/Magento/ConfigurableProductGraphQl/etc/{schema.graphql => schema.graphqls} (100%) rename app/code/Magento/CustomerGraphQl/etc/{schema.graphql => schema.graphqls} (100%) rename app/code/Magento/DownloadableGraphQl/etc/{schema.graphql => schema.graphqls} (100%) rename app/code/Magento/EavGraphQl/etc/{schema.graphql => schema.graphqls} (100%) rename app/code/Magento/GraphQl/etc/{schema.graphql => schema.graphqls} (100%) rename app/code/Magento/GroupedProductGraphQl/etc/{schema.graphql => schema.graphqls} (100%) rename app/code/Magento/SwatchesGraphQl/etc/{schema.graphql => schema.graphqls} (100%) rename app/code/Magento/TaxGraphQl/etc/{schema.graphql => schema.graphqls} (100%) rename app/code/Magento/UrlRewriteGraphQl/etc/{schema.graphql => schema.graphqls} (100%) rename app/code/Magento/WeeeGraphQl/etc/{schema.graphql => schema.graphqls} (100%) diff --git a/app/code/Magento/BundleGraphQl/etc/schema.graphql b/app/code/Magento/BundleGraphQl/etc/schema.graphqls similarity index 100% rename from app/code/Magento/BundleGraphQl/etc/schema.graphql rename to app/code/Magento/BundleGraphQl/etc/schema.graphqls diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphql b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls similarity index 100% rename from app/code/Magento/CatalogGraphQl/etc/schema.graphql rename to app/code/Magento/CatalogGraphQl/etc/schema.graphqls diff --git a/app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql b/app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphqls similarity index 100% rename from app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphql rename to app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphqls diff --git a/app/code/Magento/CmsUrlRewriteGraphQl/etc/schema.graphql b/app/code/Magento/CmsUrlRewriteGraphQl/etc/schema.graphqls similarity index 100% rename from app/code/Magento/CmsUrlRewriteGraphQl/etc/schema.graphql rename to app/code/Magento/CmsUrlRewriteGraphQl/etc/schema.graphqls diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql b/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls similarity index 100% rename from app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphql rename to app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls diff --git a/app/code/Magento/CustomerGraphQl/etc/schema.graphql b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls similarity index 100% rename from app/code/Magento/CustomerGraphQl/etc/schema.graphql rename to app/code/Magento/CustomerGraphQl/etc/schema.graphqls diff --git a/app/code/Magento/DownloadableGraphQl/etc/schema.graphql b/app/code/Magento/DownloadableGraphQl/etc/schema.graphqls similarity index 100% rename from app/code/Magento/DownloadableGraphQl/etc/schema.graphql rename to app/code/Magento/DownloadableGraphQl/etc/schema.graphqls diff --git a/app/code/Magento/EavGraphQl/etc/schema.graphql b/app/code/Magento/EavGraphQl/etc/schema.graphqls similarity index 100% rename from app/code/Magento/EavGraphQl/etc/schema.graphql rename to app/code/Magento/EavGraphQl/etc/schema.graphqls diff --git a/app/code/Magento/GraphQl/etc/schema.graphql b/app/code/Magento/GraphQl/etc/schema.graphqls similarity index 100% rename from app/code/Magento/GraphQl/etc/schema.graphql rename to app/code/Magento/GraphQl/etc/schema.graphqls diff --git a/app/code/Magento/GroupedProductGraphQl/etc/schema.graphql b/app/code/Magento/GroupedProductGraphQl/etc/schema.graphqls similarity index 100% rename from app/code/Magento/GroupedProductGraphQl/etc/schema.graphql rename to app/code/Magento/GroupedProductGraphQl/etc/schema.graphqls diff --git a/app/code/Magento/SwatchesGraphQl/etc/schema.graphql b/app/code/Magento/SwatchesGraphQl/etc/schema.graphqls similarity index 100% rename from app/code/Magento/SwatchesGraphQl/etc/schema.graphql rename to app/code/Magento/SwatchesGraphQl/etc/schema.graphqls diff --git a/app/code/Magento/TaxGraphQl/etc/schema.graphql b/app/code/Magento/TaxGraphQl/etc/schema.graphqls similarity index 100% rename from app/code/Magento/TaxGraphQl/etc/schema.graphql rename to app/code/Magento/TaxGraphQl/etc/schema.graphqls diff --git a/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphql b/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls similarity index 100% rename from app/code/Magento/UrlRewriteGraphQl/etc/schema.graphql rename to app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls diff --git a/app/code/Magento/WeeeGraphQl/etc/schema.graphql b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls similarity index 100% rename from app/code/Magento/WeeeGraphQl/etc/schema.graphql rename to app/code/Magento/WeeeGraphQl/etc/schema.graphqls diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php index d2700c44ff0fe..d8ef31d0a9a45 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php @@ -46,7 +46,7 @@ class GraphQlReader implements ReaderInterface public function __construct( FileResolverInterface $fileResolver, TypeReader $typeReader, - $fileName = 'schema.graphql', + $fileName = 'schema.graphqls', $defaultScope = 'global' ) { $this->fileResolver = $fileResolver; From 754b8fdb934271e413a6959fc92c7a0da97d4c6d Mon Sep 17 00:00:00 2001 From: Eric Bohanon Date: Mon, 26 Mar 2018 16:08:20 -0500 Subject: [PATCH 241/668] MAGETWO-88936: Fix EE functional tests --- .../Model/Resolver/BundleItems.php | 6 +- .../Model/Resolver/Options/Collection.php | 10 +- .../Query/GroupedItemsPostProcessor.php | 119 ------------------ .../GraphQl/Catalog/ProductViewTest.php | 6 + .../Catalog/VirtualProductViewTest.php | 6 + .../ConfigurableProductViewTest.php | 6 + .../Magento/GraphQl/Tax/ProductViewTest.php | 6 + 7 files changed, 34 insertions(+), 125 deletions(-) delete mode 100644 app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php index 4edc773b0b838..ea3ce56cdef92 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItems.php @@ -67,7 +67,11 @@ public function resolve(Field $field, array $value = null, array $args = null, $ return null; } - $this->bundleOptionCollection->addParentFilterData((int)$value[$linkField], $value[ProductInterface::SKU]); + $this->bundleOptionCollection->addParentFilterData( + (int)$value[$linkField], + (int)$value['entity_id'], + $value[ProductInterface::SKU] + ); $result = function () use ($value, $linkField) { return $this->bundleOptionCollection->getOptionsByParentId((int)$value[$linkField]); diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Collection.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Collection.php index 11f63f07a126d..b525e94262dd5 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Collection.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Collection.php @@ -63,9 +63,9 @@ public function __construct( * @param int $parentId * @param string $sku */ - public function addParentFilterData(int $parentId, string $sku) : void + public function addParentFilterData(int $parentId, int $parentEntityId, string $sku) : void { - $this->skuMap[$parentId] = $sku; + $this->skuMap[$parentId] = ['sku' => $sku, 'entity_id' => $parentEntityId]; } /** @@ -99,8 +99,8 @@ private function fetch() : array $optionsCollection = $this->bundleOptionFactory->create()->getResourceCollection(); // All products in collection will have same store id. $optionsCollection->joinValues($this->storeManager->getStore()->getId()); - foreach (array_keys($this->skuMap) as $id) { - $optionsCollection->setProductIdFilter($id); + foreach ($this->skuMap as $parentInfo) { + $optionsCollection->setProductIdFilter($parentInfo['entity_id']); } $optionsCollection->setPositionOrder(); @@ -118,7 +118,7 @@ private function fetch() : array $this->optionMap[$option->getParentId()][$option->getId()]['title'] = $option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle(); $this->optionMap[$option->getParentId()][$option->getId()]['sku'] - = $this->skuMap[$option->getParentId()]; + = $this->skuMap[$option->getParentId()]['sku']; } return $this->optionMap; diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php deleted file mode 100644 index 9423ddff6eb31..0000000000000 --- a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Products/Query/GroupedItemsPostProcessor.php +++ /dev/null @@ -1,119 +0,0 @@ -productDataProvider = $productDataProvider; - $this->searchCriteriaBuilder = $searchCriteriaBuilder; - $this->formatter = $formatter; - $this->productResource = $productResource; - } - - /** - * {@inheritDoc} - */ - public function process(array $resultData) : array - { - $childrenSkus = []; - foreach ($resultData as $product) { - if ($product['type_id'] === Grouped::TYPE_CODE) { - if (isset($product['items'])) { - foreach ($product['items'] as $link) { - if ($link['product']['link_type'] !== ProductLinks::LINK_TYPE) { - continue; - } - $childrenSkus[] = $link['product']['linked_product_sku']; - } - } - } - } - - $this->searchCriteriaBuilder->addFilter(ProductInterface::SKU, $childrenSkus, 'in'); - $childResults = $this->productDataProvider->getList($this->searchCriteriaBuilder->create(), []); - $resultData = $this->addChildData($childResults->getItems(), $resultData); - - return $resultData; - } - - /** - * Format and add child data of grouped products to matching grouped items - * - * @param \Magento\Catalog\Model\Product[] $childResults - * @param array $resultData - * @return array - */ - private function addChildData(array $childResults, array $resultData) : array - { - foreach ($childResults as $child) { - $childData = ['model' => $child]; - $childSku = $child->getSku(); - foreach ($resultData as $key => $item) { - foreach ($item['items'] as $linkKey => $link) { - if (!isset($link['product']['linked_product_sku']) - || $link['product']['link_type'] !== ProductLinks::LINK_TYPE - || $link['product']['linked_product_sku'] !== $childSku - ) { - continue; - } - $resultData[$key]['items'][$linkKey]['product'] = $childData; - $categoryLinks = $this->productResource->getCategoryIds($child); - foreach ($categoryLinks as $position => $catLink) { - $resultData[$key]['items'][$linkKey]['product']['category_links'][] = - ['position' => $position, 'category_id' => $catLink]; - } - } - } - } - - return $resultData; - } -} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index 8a62dc85f8808..9e93837a6be40 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -9,6 +9,7 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\Data\ProductLinkInterface; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\EntityManager\MetadataPool; use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\GraphQlAbstract; @@ -252,6 +253,11 @@ public function testQueryAllFieldsSimpleProduct() /** @var ProductRepositoryInterface $productRepository */ $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); $product = $productRepository->get($productSku, false, null, true); + /** @var MetadataPool $metadataPool */ + $metadataPool = ObjectManager::getInstance()->get(MetadataPool::class); + $product->setId( + $product->getData($metadataPool->getMetadata(ProductInterface::class)->getLinkField()) + ); $this->assertArrayHasKey('products', $response); $this->assertArrayHasKey('items', $response['products']); $this->assertEquals(1, count($response['products']['items'])); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/VirtualProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/VirtualProductViewTest.php index f78f330e7350a..93447d2eb8d7e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/VirtualProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/VirtualProductViewTest.php @@ -8,6 +8,7 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\EntityManager\MetadataPool; use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\GraphQlAbstract; @@ -56,6 +57,11 @@ public function testQueryAllFieldsVirtualProduct() /** @var ProductRepositoryInterface $productRepository */ $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); $product = $productRepository->get($productSku, false, null, true); + /** @var MetadataPool $metadataPool */ + $metadataPool = ObjectManager::getInstance()->get(MetadataPool::class); + $product->setId( + $product->getData($metadataPool->getMetadata(ProductInterface::class)->getLinkField()) + ); $this->assertArrayHasKey('products', $response); $this->assertArrayHasKey('items', $response['products']); $this->assertEquals(1, count($response['products']['items'])); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php index a2b3a02e21024..e18eb5a261542 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php @@ -8,6 +8,7 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\EntityManager\MetadataPool; use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\GraphQlAbstract; @@ -206,6 +207,11 @@ public function testQueryConfigurableProductLinks() $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); $product = $productRepository->get($productSku, false, null, true); + /** @var MetadataPool $metadataPool */ + $metadataPool = ObjectManager::getInstance()->get(MetadataPool::class); + $product->setId( + $product->getData($metadataPool->getMetadata(ProductInterface::class)->getLinkField()) + ); $this->assertArrayHasKey('products', $response); $this->assertArrayHasKey('items', $response['products']); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php index 9c737df17a39b..b5728a41e6a78 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php @@ -8,6 +8,7 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\EntityManager\MetadataPool; use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\GraphQlAbstract; use Magento\Store\Model\StoreManagerInterface; @@ -190,6 +191,11 @@ public function testQueryAllFieldsSimpleProduct() /** @var \Magento\Catalog\Model\Product $product */ $product = $this->productRepository->get($productSku, false, null, true); + /** @var MetadataPool $metadataPool */ + $metadataPool = ObjectManager::getInstance()->get(MetadataPool::class); + $product->setId( + $product->getData($metadataPool->getMetadata(ProductInterface::class)->getLinkField()) + ); $this->assertArrayHasKey('products', $response); $this->assertArrayHasKey('items', $response['products']); $this->assertEquals(1, count($response['products']['items'])); From 1703d0486da48f9fc04b0d8ee3c157eae5a47653 Mon Sep 17 00:00:00 2001 From: Eugene Tulika Date: Mon, 26 Mar 2018 20:38:29 -0500 Subject: [PATCH 242/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - updated synchronous request processor pattern - added api-functional test to verify the async bulk response --- .../Rest/SynchronousRequestProcessor.php | 4 +- .../api-functional/framework/bootstrap.php | 6 +- .../WebapiAsync/Model/BulkScheduleTest.php | 454 +++++++----------- .../WebapiAsync/WebapiAsyncBaseTestCase.php | 19 +- .../PublisherConsumerController.php | 22 +- dev/tests/integration/framework/bootstrap.php | 4 + .../Model/MessageQueue/MassScheduleTest.php | 1 - 7 files changed, 195 insertions(+), 315 deletions(-) diff --git a/app/code/Magento/Webapi/Controller/Rest/SynchronousRequestProcessor.php b/app/code/Magento/Webapi/Controller/Rest/SynchronousRequestProcessor.php index fe34a3f928fcd..b499dcbfae23b 100644 --- a/app/code/Magento/Webapi/Controller/Rest/SynchronousRequestProcessor.php +++ b/app/code/Magento/Webapi/Controller/Rest/SynchronousRequestProcessor.php @@ -18,7 +18,7 @@ */ class SynchronousRequestProcessor implements RequestProcessorInterface { - const PROCESSOR_PATH = "/^\\/V.+/"; + const PROCESSOR_PATH = "/^\\/V\\d+/"; /** * @var RestResponse @@ -112,7 +112,7 @@ public function process(\Magento\Framework\Webapi\Rest\Request $request) */ public function canProcess(\Magento\Framework\Webapi\Rest\Request $request) { - if (preg_match(self::PROCESSOR_PATH, ltrim($request->getPathInfo(), '/')) === 1) { + if (preg_match(self::PROCESSOR_PATH, $request->getPathInfo()) === 1) { return true; } return false; diff --git a/dev/tests/api-functional/framework/bootstrap.php b/dev/tests/api-functional/framework/bootstrap.php index fc4ceea393098..01580bc268d05 100644 --- a/dev/tests/api-functional/framework/bootstrap.php +++ b/dev/tests/api-functional/framework/bootstrap.php @@ -18,6 +18,10 @@ define('TESTS_TEMP_DIR', $testsBaseDir . '/tmp'); } +if (!defined('INTEGRATION_TESTS_DIR')) { + define('INTEGRATION_TESTS_DIR', $integrationTestsDir); +} + try { setCustomErrorHandler(); @@ -40,7 +44,7 @@ } $testFrameworkDir = __DIR__; - require_once __DIR__ . '/../../integration/framework/deployTestModules.php'; + require_once INTEGRATION_TESTS_DIR . '/framework/deployTestModules.php'; $installConfigFile = $settings->getAsConfigFile('TESTS_INSTALL_CONFIG_FILE'); if (!file_exists($installConfigFile)) { diff --git a/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php b/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php index 840dd7ea006c6..6f27c2bfd787c 100644 --- a/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php +++ b/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php @@ -7,16 +7,16 @@ namespace Magento\WebapiAsync\Model\MessageQueue; use Magento\Catalog\Api\Data\ProductInterface; -//use Magento\Framework\MessageQueue\Consumer\ConfigInterface as ConsumerConfigInterface; -//use Magento\MessageQueue\Model\Cron\ConsumersRunner\PidConsumerManager; -//use Magento\Framework\App\DeploymentConfig\FileReader; -//use Magento\Framework\App\DeploymentConfig\Writer; -//use Magento\Framework\Config\File\ConfigFilePool; -//use Magento\Framework\ShellInterface; -//use Magento\Framework\Filesystem; -//use Magento\Framework\App\Filesystem\DirectoryList; -//use Magento\Framework\App\Config\ReinitableConfigInterface; -use Magento\WebapiAsync\WebApiAsyncBaseTestCase; +use Magento\TestFramework\MessageQueue\PreconditionFailedException; +use Magento\TestFramework\MessageQueue\PublisherConsumerController; +use Magento\TestFramework\MessageQueue\EnvironmentPreconditionException; +use Magento\TestFramework\TestCase\WebapiAbstract; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Catalog\Model\ResourceModel\Product\Collection; +use Magento\Framework\Phrase; +use Magento\Framework\Registry; +use Magento\Framework\Webapi\Exception; +use Magento\Catalog\Api\ProductRepositoryInterface; /** * Check async request for product creation service, scheduling bulk to rabbitmq @@ -24,15 +24,14 @@ * check if product was created by async requests * * @magentoAppIsolation enabled - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class BulkScheduleTest extends WebApiAsyncBaseTestCase +class BulkScheduleTest extends WebapiAbstract { const SERVICE_NAME = 'catalogProductRepositoryV1'; const SERVICE_VERSION = 'V1'; const REST_RESOURCE_PATH = '/V1/products'; const ASYNC_RESOURCE_PATH = '/async/V1/products'; - const ASYNC_CONSUMER_NAME = 'async.V1.products.POST'; + const ASYNC_CONSUMER_NAME = 'async.operations.all'; const KEY_TIER_PRICES = 'tier_prices'; const KEY_SPECIAL_PRICE = 'special_price'; @@ -44,96 +43,63 @@ class BulkScheduleTest extends WebApiAsyncBaseTestCase self::ASYNC_CONSUMER_NAME ]; -// /** -// * @var \Magento\Framework\ObjectManagerInterface -// */ -// private $objectManager; -// -// /** -// * Consumer config provider -// * -// * @var ConsumerConfigInterface -// */ -// private $consumerConfig; -// -// /** -// * @var PidConsumerManager -// */ -// private $pid; -// -// /** -// * @var FileReader -// */ -// private $reader; -// -// /** -// * @var \Magento\MessageQueue\Model\Cron\ConsumersRunner -// */ -// private $consumersRunner; -// -// /** -// * @var Filesystem -// */ -// private $filesystem; -// -// /** -// * @var ConfigFilePool -// */ -// private $configFilePool; -// -// /** -// * @var ReinitableConfigInterface -// */ -// private $appConfig; -// -// /** -// * @var ShellInterface|\PHPUnit_Framework_MockObject_MockObject -// */ -// private $shellMock; -// -// /** -// * @var array -// */ -// private $config; - -// /** -// * @inheritdoc -// */ -// protected function setUp() -// { -// $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -// $this->shellMock = $this->getMockBuilder(ShellInterface::class) -// ->getMockForAbstractClass(); -// $this->pid = $this->objectManager->get(PidConsumerManager::class); -// $this->consumerConfig = $this->objectManager->get(ConsumerConfigInterface::class); -// $this->reader = $this->objectManager->get(FileReader::class); -// $this->filesystem = $this->objectManager->get(Filesystem::class); -// $this->configFilePool = $this->objectManager->get(ConfigFilePool::class); -// $this->appConfig = $this->objectManager->get(ReinitableConfigInterface::class); -// -// $this->consumersRunner = $this->objectManager->create( -// \Magento\MessageQueue\Model\Cron\ConsumersRunner::class, -// ['shellBackground' => $this->shellMock] -// ); -// -// $this->config = $this->loadConfig(); -// -// $this->shellMock->expects($this->any()) -// ->method('execute') -// ->willReturnCallback(function ($command, $arguments) { -// $command = vsprintf($command, $arguments); -// $params = -// \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams(); -// $params['MAGE_DIRS']['base']['path'] = BP; -// $params = -// 'INTEGRATION_TEST_PARAMS="' . urldecode(http_build_query($params)) . '"'; -// $command = -// str_replace('bin/magento', 'dev/tests/integration/bin/magento', $command); -// $command = $params . ' ' . $command; -// -// return exec("{$command} > /dev/null &"); -// }); -// } + /** + * @var string[] + */ + private $skus = []; + + /** + * @var PublisherConsumerController + */ + private $publisherConsumerController; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + + /** + * @var Registry + */ + private $registry; + + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->logFilePath = TESTS_TEMP_DIR . "/MessageQueueTestLog.txt"; + $this->registry = $this->objectManager->get(Registry::class); + + $params = array_merge_recursive( + \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams(), + ['MAGE_DIRS'=> ['cache' => ['path' => TESTS_TEMP_DIR . '/cache']]] + ); + + /** @var PublisherConsumerController publisherConsumerController */ + $this->publisherConsumerController = $this->objectManager->create(PublisherConsumerController::class, [ + 'consumers' => $this->consumers, + 'logFilePath' => $this->logFilePath, + 'appInitParams' => $params + ]); + $this->productRepository = $this->objectManager->create(ProductRepositoryInterface::class); + + try { + $this->publisherConsumerController->initialize(); + } catch (EnvironmentPreconditionException $e) { + $this->markTestSkipped($e->getMessage()); + } catch (PreconditionFailedException $e) { + $this->fail( + $e->getMessage() + ); + } + + parent::setUp(); + + } /** * @dataProvider productCreationProvider @@ -143,18 +109,85 @@ public function testAsyncScheduleBulk($product) $response = $this->saveProductAsync($product); $this->assertArrayHasKey(self::BULK_UUID_KEY, $response); $this->assertNotNull($response[self::BULK_UUID_KEY]); + + if (count($product) <= 1) { + $this->skus[] = $product['product'][ProductInterface::SKU]; + $this->assertCount(1, $response['request_items']); + $this->assertEquals('accepted', $response['request_items'][0]['status']); + $this->assertFalse($response['is_errors']); + } else { + $this->assertCount(count($product), $response['request_items']); + foreach($product as $productItem) { + $this->skus[] = $productItem['product'][ProductInterface::SKU]; + } + foreach ($response['request_items'] as $status) { + $this->assertEquals('accepted', $status['status']); + } + $this->assertFalse($response['is_errors']); + } + //assert one products is created + try { + $this->publisherConsumerController->waitForAsynchronousResult( + [$this, 'assertProductCreation'], [$product] + ); + } catch (PreconditionFailedException $e) { + $this->fail("Not all products were created"); + } + } + + public function tearDown() + { + $this->clearProducts(); + $this->publisherConsumerController->stopConsumers(); + parent::tearDown(); + } + + private function clearProducts() + { + $size = $this->objectManager->create(Collection::class) + ->addAttributeToFilter('sku', ['in' => $this->skus]) + ->load() + ->getSize(); + + if ($size == 0) { + return; + } + + $this->registry->unregister('isSecureArea'); + $this->registry->register('isSecureArea', true); + try { + foreach ($this->skus as $sku) { + $this->productRepository->deleteById($sku); + } + } catch (\Exception $e) { + throw $e; + //nothing to delete + } + $this->registry->unregister('isSecureArea'); + + $size = $this->objectManager->create(Collection::class) + ->addAttributeToFilter('sku', ['in' => $this->skus]) + ->load() + ->getSize(); + + if ($size > 0) { + throw new Exception(new Phrase("Collection size after clearing the products: %size", ['size' => $size])); + } } /** * @param string $sku * @param string|null $storeCode * @return array|bool|float|int|string + * @dataProvider productGetDataProvider + * @expectedException \Exception + * @expectedExceptionMessage Specified request cannot be processed. */ - private function getProduct($sku, $storeCode = null) + public function testGetProductAsync($sku, $storeCode = null) { $serviceInfo = [ 'rest' => [ - 'resourcePath' => self::REST_RESOURCE_PATH . '/' . $sku, + 'resourcePath' => self::ASYNC_RESOURCE_PATH . '/' . $sku, 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, ], ]; @@ -177,8 +210,22 @@ public function productCreationProvider() }; return [ - [$productBuilder([ProductInterface::TYPE_ID => 'simple', ProductInterface::SKU => 'psku-test-1'])], - [$productBuilder([ProductInterface::TYPE_ID => 'virtual', ProductInterface::SKU => 'psku-test-2'])], + [['product' => $productBuilder([ProductInterface::TYPE_ID => 'simple', ProductInterface::SKU => 'psku-test-1'])]], + [['product' => $productBuilder([ProductInterface::TYPE_ID => 'virtual', ProductInterface::SKU => 'psku-test-2'])]], + [[ + ['product' => $productBuilder([ProductInterface::TYPE_ID => 'simple', ProductInterface::SKU => 'psku-test-1'])], + ['product' => $productBuilder([ProductInterface::TYPE_ID => 'virtual', ProductInterface::SKU => 'psku-test-2'])] + ]] + ]; + } + + /** + * @return array + */ + public function productGetDataProvider() + { + return [ + ['psku-test-1', null] ]; } @@ -209,205 +256,28 @@ private function getSimpleProductData($productData = []) } /** - * @param $product + * @param $requestData * @param string|null $storeCode * @return mixed */ - private function saveProductAsync($product, $storeCode = null) + private function saveProductAsync($requestData, $storeCode = null) { - if (isset($product['custom_attributes'])) { - for ($i = 0; $i < sizeof($product['custom_attributes']); $i++) { - if ($product['custom_attributes'][$i]['attribute_code'] == 'category_ids' - && !is_array($product['custom_attributes'][$i]['value']) - ) { - $product['custom_attributes'][$i]['value'] = [""]; - } - } - } $serviceInfo = [ 'rest' => [ 'resourcePath' => self::ASYNC_RESOURCE_PATH, 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST, ], ]; - $requestData = ['product' => $product]; return $this->_webApiCall($serviceInfo, $requestData, null, $storeCode); } - /** - * Delete Product by rest request without async - * - * @param string $sku - * @return boolean - */ - private function deleteProductRest($sku) + public function assertProductCreation($product) { - $serviceInfo = [ - 'rest' => [ - 'resourcePath' => self::REST_RESOURCE_PATH . '/' . $sku, - 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE, - ], - ]; - - return $this->_webApiCall($serviceInfo, ['sku' => $sku]); - } - - /** - * @dataProvider productCreationProvider - */ - public function testAsyncProductCreation($product) - { - $restProduct = $this->getProduct($product[ProductInterface::SKU]); - $this->assertArrayHasKey('id', $restProduct); - $this->assertGreaterThan(0, $restProduct['id']); - $this->deleteProductRest($product[ProductInterface::SKU]);//removing product immediately after test passed + $collection = $this->objectManager->create(Collection::class) + ->addAttributeToFilter('sku', ['in' => $this->skus]) + ->load(); + $size = $collection->getSize(); + return $size == count($this->skus); } - -// /** -// * Checks that pid files are created -// * -// * @return void -// */ -// public function testCheckThatAsyncPidFilesWasCreated() -// { -// $config = $this->config; -// $config['cron_consumers_runner'] = ['cron_run' => true]; -// $this->writeConfig($config); -// -// $this->consumersRunner->run(); -// -// foreach ($this->consumerConfig->getConsumers() as $consumer) { -// if ($consumer->getName() == self::ASYNC_CONSUMER_NAME) { -// $this->waitConsumerPidFile($consumer->getName()); -// } -// } -// } -// -// /** -// * Tests running of specific consumer and his re-running when it is working -// * -// * @return void -// */ -// public function testAsyncConsumerAndRerun() -// { -// $specificConsumer = self::ASYNC_CONSUMER_NAME; -// $config = $this->config; -// $config['cron_consumers_runner'] = -// ['consumers' => [$specificConsumer], 'max_messages' => null, 'cron_run' => true]; -// $this->writeConfig($config); -// -// $this->reRunConsumersAndCheckPidFiles($specificConsumer); -// $this->assertGreaterThan(0, $this->pid->getPid($specificConsumer)); -// } - - -// /** -// * @param string $specificConsumer -// * @return void -// */ -// private function reRunConsumersAndCheckPidFiles($specificConsumer) -// { -// $this->consumersRunner->run(); -// -// sleep(20); -// -// foreach ($this->consumerConfig->getConsumers() as $consumer) { -// $consumerName = $consumer->getName(); -// $pidFilePath = $this->pid->getPidFilePath($consumerName); -// -// if ($consumerName === $specificConsumer) { -// $this->assertTrue(file_exists($pidFilePath)); -// } else { -// $this->assertFalse(file_exists($pidFilePath)); -// } -// } -// } -// -// /** -// * Tests disabling cron job which runs consumers -// * -// * @return void -// */ -// public function testCronJobDisabled() -// { -// $config = $this->config; -// $config['cron_consumers_runner'] = ['cron_run' => false]; -// -// $this->writeConfig($config); -// -// $this->consumersRunner->run(); -// -// sleep(20); -// -// foreach ($this->consumerConfig->getConsumers() as $consumer) { -// $pidFilePath = $this->pid->getPidFilePath($consumer->getName()); -// $this->assertFalse(file_exists($pidFilePath)); -// } -// } -// -// /** -// * @param string $consumerName -// * @return void -// */ -// private function waitConsumerPidFile($consumerName) -// { -// $pidFilePath = $this->pid->getPidFilePath($consumerName); -// $i = 0; -// do { -// sleep(1); -// } while (!file_exists($pidFilePath) && ($i++ < 60)); -// -// sleep(30); -// -// if (!file_exists($pidFilePath)) { -// $this->fail($consumerName . ' pid file does not exist.'); -// } -// } -// -// /** -// * @return array -// */ -// private function loadConfig() -// { -// return $this->reader->load(ConfigFilePool::APP_ENV); -// } -// -// /** -// * @param array $config -// * @return void -// */ -// private function writeConfig(array $config) -// { -// /** @var Writer $writer */ -// $writer = $this->objectManager->get(Writer::class); -// $writer->saveConfig([ConfigFilePool::APP_ENV => $config]); -// } -// -// /** -// * @inheritdoc -// */ -// protected function tearDown() -// { -// foreach ($this->consumerConfig->getConsumers() as $consumer) { -// $consumerName = $consumer->getName(); -// $pid = $this->pid->getPid($consumerName); -// -// if ($pid && $this->pid->isRun($consumerName)) { -// posix_kill($pid, SIGKILL); -// } -// -// $path = $this->pid->getPidFilePath($consumerName); -// if (file_exists($path)) { -// unlink($path); -// } -// } -// -// $this->filesystem->getDirectoryWrite(DirectoryList::CONFIG)->writeFile( -// $this->configFilePool->getPath(ConfigFilePool::APP_ENV), -// "writeConfig($this->config); -// $this->appConfig->reinit(); -// } } diff --git a/dev/tests/api-functional/testsuite/Magento/WebapiAsync/WebapiAsyncBaseTestCase.php b/dev/tests/api-functional/testsuite/Magento/WebapiAsync/WebapiAsyncBaseTestCase.php index 6b31ca2c0f2e9..8b187c5e54f87 100644 --- a/dev/tests/api-functional/testsuite/Magento/WebapiAsync/WebapiAsyncBaseTestCase.php +++ b/dev/tests/api-functional/testsuite/Magento/WebapiAsync/WebapiAsyncBaseTestCase.php @@ -44,9 +44,9 @@ class WebApiAsyncBaseTestCase extends WebapiAbstract /** * @var PublisherConsumerController */ - private $publisherConsumerController; + protected $publisherConsumerController; - protected function setUp() + public function setUp() { $this->objectManager = Bootstrap::getObjectManager(); $this->publisherConsumerController = $this->objectManager->create(PublisherConsumerController::class, [ @@ -73,21 +73,6 @@ protected function tearDown() parent::tearDown(); } - /** - * Wait for asynchronous handlers to log data to file. - * - * @param int $expectedLinesCount - * @param string $logFilePath - */ - protected function waitForAsynchronousResult($expectedLinesCount, $logFilePath) - { - try { - $this->publisherConsumerController->waitForAsynchronousResult($expectedLinesCount, $logFilePath); - } catch (PreconditionFailedException $e) { - $this->fail($e->getMessage()); - } - } - /** * Workaround for https://bugs.php.net/bug.php?id=72286 */ diff --git a/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PublisherConsumerController.php b/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PublisherConsumerController.php index 18f8d24c3c59b..b535989e43e40 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PublisherConsumerController.php +++ b/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PublisherConsumerController.php @@ -35,6 +35,11 @@ class PublisherConsumerController */ private $osInfo; + /** + * @var array + */ + private $appInitParams; + public function __construct( PublisherInterface $publisher, OsInfo $osInfo, @@ -48,6 +53,7 @@ public function __construct( $this->logFilePath = $logFilePath; $this->maxMessages = $maxMessages; $this->osInfo = $osInfo; + $this->appInitParams = $appInitParams; } /** @@ -97,6 +103,18 @@ public function stopConsumers() } } + /** + * @return array + */ + public function getConsumersProcessIds() + { + $consumers = []; + foreach ($this->consumers as $consumer) { + $consumers[$consumer] = $this->getConsumerProcessIds($consumer); + } + return $consumers; + } + /** * @param string $consumer * @return string[] @@ -116,14 +134,14 @@ private function getConsumerProcessIds($consumer) */ private function getConsumerStartCommand($consumer, $withEnvVariables = false) { - $binDirectory = realpath(TESTS_TEMP_DIR . '/../bin/'); + $binDirectory = realpath(INTEGRATION_TESTS_DIR . '/bin/'); $magentoCli = $binDirectory . '/magento'; $consumerStartCommand = "php {$magentoCli} queue:consumers:start -vvv " . $consumer; if ($this->maxMessages) { $consumerStartCommand .= " --max-messages={$this->maxMessages}"; } if ($withEnvVariables) { - $params = \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams(); + $params = $this->appInitParams; $params['MAGE_DIRS']['base']['path'] = BP; $params = 'INTEGRATION_TEST_PARAMS="' . urldecode(http_build_query($params)) . '"'; $consumerStartCommand = $params . ' ' . $consumerStartCommand; diff --git a/dev/tests/integration/framework/bootstrap.php b/dev/tests/integration/framework/bootstrap.php index 4e14c8113a708..1cae393dc01c3 100644 --- a/dev/tests/integration/framework/bootstrap.php +++ b/dev/tests/integration/framework/bootstrap.php @@ -15,6 +15,10 @@ define('TESTS_TEMP_DIR', $testsBaseDir . '/tmp'); } +if (!defined('INTEGRATION_TESTS_DIR')) { + define('INTEGRATION_TESTS_DIR', $testsBaseDir); +} + $testFrameworkDir = __DIR__; require_once 'deployTestModules.php'; diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/MassScheduleTest.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/MassScheduleTest.php index 68a1244ffa824..93dfb429e26ee 100644 --- a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/MassScheduleTest.php +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/MassScheduleTest.php @@ -69,7 +69,6 @@ class MassScheduleTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->objectManager = Bootstrap::getObjectManager(); $this->registry = $this->objectManager->get(Registry::class); $this->massSchedule = $this->objectManager->create(MassSchedule::class); From 6babc1b84fd23baca8796cff822428967349d6c3 Mon Sep 17 00:00:00 2001 From: Eugene Tulika Date: Mon, 26 Mar 2018 21:19:46 -0500 Subject: [PATCH 243/668] magento-engcom/bulk-api#7 Add extension point to WebAPI - removed ItemsListInterface --- .../Data/AsyncResponse/ItemsListInterface.php | 56 ------------ .../Model/AsyncResponse/ItemsList.php | 90 ------------------- app/code/Magento/WebapiAsync/etc/di.xml | 10 --- .../WebapiAsync/etc/webapi_rest/di.xml | 1 - 4 files changed, 157 deletions(-) delete mode 100644 app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemsListInterface.php delete mode 100644 app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemsList.php diff --git a/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemsListInterface.php b/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemsListInterface.php deleted file mode 100644 index 1c29adbb3f8fc..0000000000000 --- a/app/code/Magento/WebapiAsync/Api/Data/AsyncResponse/ItemsListInterface.php +++ /dev/null @@ -1,56 +0,0 @@ -items = $items; - $this->groupId = $groupId; - $this->isErrors = $isError; - } - - /** - * @inheritdoc - */ - public function setItems($items) - { - $this->items = $items; - return $this; - } - - /** - * @inheritdoc - */ - public function setGroupId($groupId) - { - $this->groupId = $groupId; - return $this; - } - - /** - * @inheritdoc - */ - public function getItems() - { - return $this->items; - } - - /** - * @inheritdoc - */ - public function getGroupId() - { - return $this->groupId; - } - - /** - * @inheritdoc - */ - public function setIsErrors($isErrors = false) - { - $this->isErrors = $isErrors; - } - - /** - * @inheritdoc - */ - public function getIsErrors() - { - return $this->isErrors; - } -} diff --git a/app/code/Magento/WebapiAsync/etc/di.xml b/app/code/Magento/WebapiAsync/etc/di.xml index 3263266d44fb4..991afa556b35b 100755 --- a/app/code/Magento/WebapiAsync/etc/di.xml +++ b/app/code/Magento/WebapiAsync/etc/di.xml @@ -9,16 +9,6 @@ xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - - - - diff --git a/app/code/Magento/WebapiAsync/etc/webapi_rest/di.xml b/app/code/Magento/WebapiAsync/etc/webapi_rest/di.xml index d2f97f62baf5d..9e7fd21a235a3 100644 --- a/app/code/Magento/WebapiAsync/etc/webapi_rest/di.xml +++ b/app/code/Magento/WebapiAsync/etc/webapi_rest/di.xml @@ -16,5 +16,4 @@ - \ No newline at end of file From 0ae610850ec0d248f6dc1f690381efe85f18eeec Mon Sep 17 00:00:00 2001 From: Joan He Date: Tue, 27 Mar 2018 00:44:28 -0500 Subject: [PATCH 244/668] MAGETWO-89567: Cannot set 'user' save handler by ini_set() --- .../Magento/Framework/Session/ConfigTest.php | 192 +++++++++++------- .../Framework/Session/SaveHandlerTest.php | 127 ++++++++---- .../Magento/Framework/Session/SaveHandler.php | 35 +--- 3 files changed, 207 insertions(+), 147 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php index 3e7f989ca39f7..e31ea2a124fd1 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php @@ -12,9 +12,6 @@ */ class ConfigTest extends \PHPUnit\Framework\TestCase { - /** @var \Magento\Framework\Session\Config */ - private $_model; - /** @var string */ private $_cacheLimiter = 'private_no_expire'; @@ -45,10 +42,6 @@ protected function setUp() } }); - $this->_model = $this->_objectManager->create( - \Magento\Framework\Session\Config::class, - ['deploymentConfig' => $this->deploymentConfigMock] - ); $this->defaultSavePath = $this->_objectManager ->get(\Magento\Framework\Filesystem\DirectoryList::class) ->getPath(DirectoryList::SESSION); @@ -59,6 +52,7 @@ protected function setUp() */ public function testDefaultConfiguration() { + $model = $this->getModel(); /** @var \Magento\Framework\Filesystem $filesystem */ $filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( \Magento\Framework\Filesystem::class @@ -68,25 +62,26 @@ public function testDefaultConfiguration() $this->assertEquals( $path, - $this->_model->getSavePath() + $model->getSavePath() ); $this->assertEquals( \Magento\Framework\Session\Config::COOKIE_LIFETIME_DEFAULT, - $this->_model->getCookieLifetime() + $model->getCookieLifetime() ); - $this->assertEquals($this->_cacheLimiter, $this->_model->getCacheLimiter()); - $this->assertEquals('/', $this->_model->getCookiePath()); - $this->assertEquals('localhost', $this->_model->getCookieDomain()); - $this->assertEquals(false, $this->_model->getCookieSecure()); - $this->assertEquals(true, $this->_model->getCookieHttpOnly()); - $this->assertEquals($this->_model->getSavePath(), $this->_model->getOption('save_path')); + $this->assertEquals($this->_cacheLimiter, $model->getCacheLimiter()); + $this->assertEquals('/', $model->getCookiePath()); + $this->assertEquals('localhost', $model->getCookieDomain()); + $this->assertEquals(false, $model->getCookieSecure()); + $this->assertEquals(true, $model->getCookieHttpOnly()); + $this->assertEquals($model->getSavePath(), $model->getOption('save_path')); } public function testSetOptionsInvalidValue() { - $preValue = $this->_model->getOptions(); - $this->_model->setOptions(''); - $this->assertEquals($preValue, $this->_model->getOptions()); + $model = $this->getModel(); + $preValue = $model->getOptions(); + $model->setOptions(''); + $this->assertEquals($preValue, $model->getOptions()); } /** @@ -94,9 +89,10 @@ public function testSetOptionsInvalidValue() */ public function testSetOptions($option, $getter, $value) { + $model = $this->getModel(); $options = [$option => $value]; - $this->_model->setOptions($options); - $this->assertSame($value, $this->_model->{$getter}()); + $model->setOptions($options); + $this->assertSame($value, $model->{$getter}()); } public function optionsProvider() @@ -129,143 +125,178 @@ public function optionsProvider() public function testNameIsMutable() { - $this->_model->setName('FOOBAR'); - $this->assertEquals('FOOBAR', $this->_model->getName()); + $model = $this->getModel(); + $model->setName('FOOBAR'); + $this->assertEquals('FOOBAR', $model->getName()); } public function testCookieLifetimeIsMutable() { - $this->_model->setCookieLifetime(20); - $this->assertEquals(20, $this->_model->getCookieLifetime()); + $model = $this->getModel(); + $model->setCookieLifetime(20); + $this->assertEquals(20, $model->getCookieLifetime()); } public function testCookieLifetimeCanBeZero() { - $this->_model->setCookieLifetime(0); - $this->assertEquals(0, $this->_model->getCookieLifetime()); + $model = $this->getModel(); + $model->setCookieLifetime(0); + $this->assertEquals(0, $model->getCookieLifetime()); } public function testSettingInvalidCookieLifetime() { - $preVal = $this->_model->getCookieLifetime(); - $this->_model->setCookieLifetime('foobar_bogus'); - $this->assertEquals($preVal, $this->_model->getCookieLifetime()); + $model = $this->getModel(); + $preVal = $model->getCookieLifetime(); + $model->setCookieLifetime('foobar_bogus'); + $this->assertEquals($preVal, $model->getCookieLifetime()); } public function testSettingInvalidCookieLifetime2() { - $preVal = $this->_model->getCookieLifetime(); - $this->_model->setCookieLifetime(-1); - $this->assertEquals($preVal, $this->_model->getCookieLifetime()); + $model = $this->getModel(); + $preVal = $model->getCookieLifetime(); + $model->setCookieLifetime(-1); + $this->assertEquals($preVal, $model->getCookieLifetime()); } public function testWrongMethodCall() { + $model = $this->getModel(); $this->expectException( '\BadMethodCallException', 'Method "methodThatNotExist" does not exist in Magento\Framework\Session\Config' ); - $this->_model->methodThatNotExist(); + $model->methodThatNotExist(); } public function testCookieSecureDefaultsToIniSettings() { - $this->assertSame((bool)ini_get('session.cookie_secure'), $this->_model->getCookieSecure()); + $model = $this->getModel(); + $this->assertSame((bool)ini_get('session.cookie_secure'), $model->getCookieSecure()); } public function testSetCookieSecureInOptions() { - $this->_model->setCookieSecure(true); - $this->assertTrue($this->_model->getCookieSecure()); + $model = $this->getModel(); + $model->setCookieSecure(true); + $this->assertTrue($model->getCookieSecure()); } public function testCookieDomainIsMutable() { - $this->_model->setCookieDomain('example.com'); - $this->assertEquals('example.com', $this->_model->getCookieDomain()); + $model = $this->getModel(); + $model->setCookieDomain('example.com'); + $this->assertEquals('example.com', $model->getCookieDomain()); } public function testCookieDomainCanBeEmpty() { - $this->_model->setCookieDomain(''); - $this->assertEquals('', $this->_model->getCookieDomain()); + $model = $this->getModel(); + $model->setCookieDomain(''); + $this->assertEquals('', $model->getCookieDomain()); } public function testSettingInvalidCookieDomain() { - $preVal = $this->_model->getCookieDomain(); - $this->_model->setCookieDomain(24); - $this->assertEquals($preVal, $this->_model->getCookieDomain()); + $model = $this->getModel(); + $preVal = $model->getCookieDomain(); + $model->setCookieDomain(24); + $this->assertEquals($preVal, $model->getCookieDomain()); } public function testSettingInvalidCookieDomain2() { - $preVal = $this->_model->getCookieDomain(); - $this->_model->setCookieDomain('D:\\WINDOWS\\System32\\drivers\\etc\\hosts'); - $this->assertEquals($preVal, $this->_model->getCookieDomain()); + $model = $this->getModel(); + $preVal = $model->getCookieDomain(); + $model->setCookieDomain('D:\\WINDOWS\\System32\\drivers\\etc\\hosts'); + $this->assertEquals($preVal, $model->getCookieDomain()); } public function testSetCookieHttpOnlyInOptions() { - $this->_model->setCookieHttpOnly(true); - $this->assertTrue($this->_model->getCookieHttpOnly()); + $model = $this->getModel(); + $model->setCookieHttpOnly(true); + $this->assertTrue($model->getCookieHttpOnly()); } public function testUseCookiesDefaultsToIniSettings() { - $this->assertSame((bool)ini_get('session.use_cookies'), $this->_model->getUseCookies()); + $model = $this->getModel(); + $this->assertSame((bool)ini_get('session.use_cookies'), $model->getUseCookies()); } public function testSetUseCookiesInOptions() { - $this->_model->setUseCookies(true); - $this->assertTrue($this->_model->getUseCookies()); + $model = $this->getModel(); + $model->setUseCookies(true); + $this->assertTrue($model->getUseCookies()); } public function testUseOnlyCookiesDefaultsToIniSettings() { - $this->assertSame((bool)ini_get('session.use_only_cookies'), $this->_model->getUseOnlyCookies()); + $model = $this->getModel(); + $this->assertSame((bool)ini_get('session.use_only_cookies'), $model->getUseOnlyCookies()); } public function testSetUseOnlyCookiesInOptions() { - $this->_model->setOption('use_only_cookies', true); - $this->assertTrue((bool)$this->_model->getOption('use_only_cookies')); + $model = $this->getModel(); + $model->setOption('use_only_cookies', true); + $this->assertTrue((bool)$model->getOption('use_only_cookies')); } public function testRefererCheckDefaultsToIniSettings() { - $this->assertSame(ini_get('session.referer_check'), $this->_model->getRefererCheck()); + $model = $this->getModel(); + $this->assertSame(ini_get('session.referer_check'), $model->getRefererCheck()); } public function testRefererCheckIsMutable() { - $this->_model->setOption('referer_check', 'FOOBAR'); - $this->assertEquals('FOOBAR', $this->_model->getOption('referer_check')); + $model = $this->getModel(); + $model->setOption('referer_check', 'FOOBAR'); + $this->assertEquals('FOOBAR', $model->getOption('referer_check')); } public function testRefererCheckMayBeEmpty() { - $this->_model->setOption('referer_check', ''); - $this->assertEquals('', $this->_model->getOption('referer_check')); + $model = $this->getModel(); + $model->setOption('referer_check', ''); + $this->assertEquals('', $model->getOption('referer_check')); } public function testSetSavePath() { - $this->_model->setSavePath('some_save_path'); - $this->assertEquals($this->_model->getOption('save_path'), 'some_save_path'); + $model = $this->getModel(); + $model->setSavePath('some_save_path'); + $this->assertEquals($model->getOption('save_path'), 'some_save_path'); } /** - * @dataProvider savePathDataProvider + * @param string|null $existingSavePath + * @param $givenSavePath + * @param $expectedSavePath + * @param $givenSaveHandler + * @param $expectedSaveHandler + * @dataProvider constructorDataProvider */ - public function testConstructorSavePath($existing, $given, $expected) - { + public function testConstructor( + $existingSavePath, + $givenSavePath, + $expectedSavePath, + $givenSaveHandler, + $expectedSaveHandler + ) { $sessionSavePath = ini_get('session.save_path'); - if ($expected === 'default') { - $expected = $this->defaultSavePath . '/'; + $sessionSaveHandler = ini_get('session.save_handler'); + if ($expectedSavePath === 'default') { + $expectedSavePath = $this->defaultSavePath . '/'; + } + if ($expectedSaveHandler === 'php') { + $expectedSaveHandler = $sessionSaveHandler; } - $setup = ini_set('session.save_path', $existing); + $setup = ini_set('session.save_path', $existingSavePath); if ($setup === false) { $this->markTestSkipped('Cannot set session.save_path with ini_set'); } @@ -273,14 +304,14 @@ public function testConstructorSavePath($existing, $given, $expected) $deploymentConfigMock = $this->createMock(\Magento\Framework\App\DeploymentConfig::class); $deploymentConfigMock ->method('get') - ->willReturnCallback(function ($configPath) use ($given) { + ->willReturnCallback(function ($configPath) use ($givenSavePath, $givenSaveHandler) { switch ($configPath) { case Config::PARAM_SESSION_SAVE_METHOD: - return 'files'; + return $givenSaveHandler; case Config::PARAM_SESSION_CACHE_LIMITER: return $this->_cacheLimiter; case Config::PARAM_SESSION_SAVE_PATH: - return $given; + return $givenSavePath; default: return null; } @@ -290,23 +321,32 @@ public function testConstructorSavePath($existing, $given, $expected) \Magento\Framework\Session\Config::class, ['deploymentConfig' => $deploymentConfigMock] ); - $this->assertEquals($expected, $model->getOption('save_path')); + $this->assertEquals($expectedSavePath, $model->getOption('save_path')); + $this->assertEquals($expectedSaveHandler, $model->getOption('session.save_handler')); if ($sessionSavePath != ini_get('session.save_path')) { ini_set('session.save_path', $sessionSavePath); } } - public function savePathDataProvider() + public function constructorDataProvider() { // preset value (null = not set), input value (null = not set), expected value $savePathGiven = 'explicit_save_path'; $presetPath = 'preset_save_path'; return [ - [null, $savePathGiven, $savePathGiven], - [null, null, 'default'], - [$presetPath, $savePathGiven, $savePathGiven], - [$presetPath, null, $presetPath], + [null, $savePathGiven, $savePathGiven, 'db', 'db'], + [null, null, 'default', null, 'php'], + [$presetPath, $savePathGiven, $savePathGiven, 'redis', 'redis'], + [$presetPath, null, $presetPath, 'files', 'files'], ]; } + + private function getModel(): \Magento\Framework\Session\Config + { + return $this->_objectManager->create( + \Magento\Framework\Session\Config::class, + ['deploymentConfig' => $this->deploymentConfigMock] + ); + } } diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php index d2c73dff1e03a..391ae4324e04f 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php @@ -11,12 +11,34 @@ class SaveHandlerTest extends \PHPUnit\Framework\TestCase { - /** @var string Original session.save_handler ini config value */ - private $originalSaveHandler; + /** + * @var \Magento\TestFramework\ObjectManager + */ + private $objectManager; + + /** + * @var DeploymentConfig|\PHPUnit_Framework_MockObject_MockObject + */ + private $deploymentConfigMock; + + /** + * @var SaveHandlerFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $saveHandlerFactoryMock; + + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->deploymentConfigMock = $this->createMock(DeploymentConfig::class); + $this->objectManager->addSharedInstance($this->deploymentConfigMock, DeploymentConfig::class); + $this->saveHandlerFactoryMock = $this->createMock(SaveHandlerFactory::class); + $this->objectManager->addSharedInstance($this->saveHandlerFactoryMock, SaveHandlerFactory::class); + } - public function setUp() + protected function tearDown() { - $this->originalSaveHandler = ini_get('session.save_handler'); + $this->objectManager->removeSharedInstance(DeploymentConfig::class); + $this->objectManager->removeSharedInstance(SaveHandlerFactory::class); } /** @@ -24,45 +46,45 @@ public function setUp() * * @dataProvider saveHandlerProvider * @param string $deploymentConfigHandler - * @param string $iniHandler */ - public function testSetSaveHandler($deploymentConfigHandler, $iniHandler) + public function testConstructor($deploymentConfigHandler) { - $expected = $this->getExpectedSaveHandler($deploymentConfigHandler, $iniHandler); + $expected = $this->getExpectedSaveHandler($deploymentConfigHandler, ini_get('session.save_handler')); - // Set ini configuration - if ($iniHandler) { - ini_set('session.save_handler', $iniHandler); - } - $defaultHandler = ini_get('session.save_handler') ?: SaveHandlerInterface::DEFAULT_HANDLER; - /** @var DeploymentConfig | \PHPUnit_Framework_MockObject_MockObject $deploymentConfigMock */ - $deploymentConfigMock = $this->getMockBuilder(DeploymentConfig::class) - ->disableOriginalConstructor() - ->getMock(); - $deploymentConfigMock->expects($this->once()) - ->method('get') - ->with(Config::PARAM_SESSION_SAVE_METHOD, $defaultHandler) - ->willReturn($deploymentConfigHandler ?: SaveHandlerInterface::DEFAULT_HANDLER); + $this->deploymentConfigMock->method('get') + ->willReturnCallback(function ($configPath) use ($deploymentConfigHandler) { + switch ($configPath) { + case Config::PARAM_SESSION_SAVE_METHOD: + return $deploymentConfigHandler; + case Config::PARAM_SESSION_CACHE_LIMITER: + return 'private_no_expire'; + case Config::PARAM_SESSION_SAVE_PATH: + return 'explicit_save_path'; + default: + return null; + } + }); - new SaveHandler( - ObjectManager::getInstance()->get(SaveHandlerFactory::class), - $deploymentConfigMock - ); + $this->saveHandlerFactoryMock->expects($this->once()) + ->method('create') + ->with($expected); + $sessionConfig = $this->objectManager->create(ConfigInterface::class); + $this->objectManager->create(SaveHandler::class, ['sessionConfig' => $sessionConfig]); // Test expectation $this->assertEquals( $expected, - ObjectManager::getInstance()->get(ConfigInterface::class)->getOption('session.save_handler') + $sessionConfig->getOption('session.save_handler') ); } public function saveHandlerProvider() { return [ - ['db', false], - ['db', 'files'], - [false, 'files'], - [false, false], + ['db'], + ['redis'], + ['files'], + [false], ]; } @@ -75,21 +97,44 @@ public function saveHandlerProvider() */ private function getExpectedSaveHandler($deploymentConfigHandler, $iniHandler) { - // Set expected session.save_handler config if ($deploymentConfigHandler) { - if ($deploymentConfigHandler !== 'files') { - $expected = 'user'; - return $expected; - } else { - $expected = $deploymentConfigHandler; - return $expected; - } + return $deploymentConfigHandler; } elseif ($iniHandler) { - $expected = $iniHandler; - return $expected; + return $iniHandler; } else { - $expected = SaveHandlerInterface::DEFAULT_HANDLER; - return $expected; + return SaveHandlerInterface::DEFAULT_HANDLER; } } + + public function testConstructorWithException() + { + $this->deploymentConfigMock->method('get') + ->willReturnCallback(function ($configPath) { + switch ($configPath) { + case Config::PARAM_SESSION_SAVE_METHOD: + return 'db'; + case Config::PARAM_SESSION_CACHE_LIMITER: + return 'private_no_expire'; + case Config::PARAM_SESSION_SAVE_PATH: + return 'explicit_save_path'; + default: + return null; + } + }); + + $this->saveHandlerFactoryMock->expects($this->at(0)) + ->method('create') + ->willThrowException(new \LogicException()); + $this->saveHandlerFactoryMock->expects($this->at(1)) + ->method('create') + ->with(SaveHandlerInterface::DEFAULT_HANDLER); + $sessionConfig = $this->objectManager->create(ConfigInterface::class); + $this->objectManager->create(SaveHandler::class, ['sessionConfig' => $sessionConfig]); + + // Test expectation + $this->assertEquals( + 'db', + $sessionConfig->getOption('session.save_handler') + ); + } } diff --git a/lib/internal/Magento/Framework/Session/SaveHandler.php b/lib/internal/Magento/Framework/Session/SaveHandler.php index 1e95668004a2f..a889ab5662729 100644 --- a/lib/internal/Magento/Framework/Session/SaveHandler.php +++ b/lib/internal/Magento/Framework/Session/SaveHandler.php @@ -5,8 +5,6 @@ */ namespace Magento\Framework\Session; -use Magento\Framework\App\DeploymentConfig; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Session\Config\ConfigInterface; /** @@ -21,23 +19,16 @@ class SaveHandler implements SaveHandlerInterface */ protected $saveHandlerAdapter; - /** - * Config - * - * @var ConfigInterface - */ - private $config; - /** * Constructor * * @param SaveHandlerFactory $saveHandlerFactory - * @param DeploymentConfig $deploymentConfig + * @param ConfigInterface $sessionConfig * @param string $default */ public function __construct( SaveHandlerFactory $saveHandlerFactory, - DeploymentConfig $deploymentConfig, + ConfigInterface $sessionConfig, $default = self::DEFAULT_HANDLER ) { /** @@ -46,15 +37,13 @@ public function __construct( * Save handler may be set to custom value in deployment config, which will override everything else. * Otherwise, try to read PHP settings for session.save_handler value. Otherwise, use 'files' as default. */ - $defaultSaveHandler = ini_get('session.save_handler') ?: SaveHandlerInterface::DEFAULT_HANDLER; - $saveMethod = $this->getConfig()->getOption('session.save_handler') ?: $defaultSaveHandler; + $saveMethod = $sessionConfig->getOption('session.save_handler') ?: $default; try { - $connection = $saveHandlerFactory->create($saveMethod); + $this->saveHandlerAdapter = $saveHandlerFactory->create($saveMethod); } catch (\LogicException $e) { - $connection = $saveHandlerFactory->create($default); + $this->saveHandlerAdapter = $saveHandlerFactory->create($default); } - $this->saveHandlerAdapter = $connection; } /** @@ -125,18 +114,4 @@ public function gc($maxLifetime) { return $this->saveHandlerAdapter->gc($maxLifetime); } - - /** - * Get config - * - * @return ConfigInterface - * @deprecated 100.0.8 - */ - private function getConfig() - { - if ($this->config === null) { - $this->config = ObjectManager::getInstance()->get(ConfigInterface::class); - } - return $this->config; - } } From c59e4dc5001a8c7b7c86546da4bcc7b3f3830179 Mon Sep 17 00:00:00 2001 From: olysenko Date: Tue, 27 Mar 2018 13:33:13 +0300 Subject: [PATCH 245/668] MAGETWO-89382: Automate MAGETWO-46344 MFTF --- .../ActionGroup/MoveCategoryActionGroup.xml | 11 +-- .../StorefrontCategoryActionGroup.xml | 2 +- .../StorefrontProductActionGroup.xml | 13 ---- .../Catalog/Data/ProductData.xml | 15 ++++ .../Catalog/Page/AdminCategoryPage.xml | 1 - .../Section/AdminCategoryModalSection.xml | 2 +- .../AdminCategorySidebarTreeSection.xml | 1 - ...minCategoryWarningMessagesPopupSection.xml | 16 ---- .../Catalog/Test/DeleteCategoriesTest.xml | 76 +++++++++---------- 9 files changed, 61 insertions(+), 76 deletions(-) delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryWarningMessagesPopupSection.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/MoveCategoryActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/MoveCategoryActionGroup.xml index d08dc9ad7f893..9a082efa75db6 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/MoveCategoryActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/MoveCategoryActionGroup.xml @@ -15,9 +15,10 @@ - - - - + + + + + - \ No newline at end of file + \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontCategoryActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontCategoryActionGroup.xml index af71e1520bf44..3b04df7fdd115 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontCategoryActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontCategoryActionGroup.xml @@ -12,7 +12,7 @@ - + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontProductActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontProductActionGroup.xml index ddefa1a839804..ffc1687bc9f58 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontProductActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontProductActionGroup.xml @@ -23,17 +23,4 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductData.xml index 231bcd5b427d2..9090c4669dc24 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductData.xml @@ -133,4 +133,19 @@ EavStockItem CustomAttributeCategoryIds + + testProductWithDescriptionSku + simple + 4 + 4 + testProductWithDescriptionName + 123.00 + testproductwithdescriptionurlkey + 1 + 100 + EavStockItem + CustomAttributeCategoryIds + ApiProductDescription + ApiProductShortDescription + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/AdminCategoryPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/AdminCategoryPage.xml index 7cb4ca0e7987d..f51d2e8a28939 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/AdminCategoryPage.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/AdminCategoryPage.xml @@ -18,6 +18,5 @@
-
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryModalSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryModalSection.xml index 7435e759e29d1..d36256bf75d81 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryModalSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryModalSection.xml @@ -12,6 +12,6 @@ - +
\ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySidebarTreeSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySidebarTreeSection.xml index 9c8ee70874372..e914c80c3e6ac 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySidebarTreeSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySidebarTreeSection.xml @@ -14,6 +14,5 @@ -
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryWarningMessagesPopupSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryWarningMessagesPopupSection.xml deleted file mode 100644 index 6f9b0738a451e..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryWarningMessagesPopupSection.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - -
- - - -
-
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml index c4de4866519e0..6c8d1885ac8dc 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml @@ -16,21 +16,21 @@ - + - + - + - + @@ -40,9 +40,9 @@ - - - + + + @@ -55,44 +55,45 @@ - + - + - + - + - + - + + - - - - + + + + - + - + + - - + @@ -103,25 +104,24 @@ - - + + - - + - - + + @@ -130,32 +130,32 @@ - + - + - + - + - - - - - - - + + + + + + + \ No newline at end of file From 8ee5a698fc67dc1164bcb9bb1cb9c8b6e5b598aa Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko Date: Tue, 27 Mar 2018 13:39:07 +0300 Subject: [PATCH 246/668] MAGETWO-86939: Support Category Type --- .../Model/ResourceModel/CategoryProduct.php | 43 ---- .../CatalogGraphQl/Model/AttributesJoiner.php | 31 +++ .../Model/CategoryInterfaceTypeResolver.php | 25 +++ .../Model/Config/CategoryAttributeReader.php | 102 ++++++++++ .../Resolver/Categories/Query/Filter.php | 71 ------- .../Resolver/Categories/Query/Search.php | 52 ----- .../Model/Resolver/Category.php | 115 +++++++++++ .../Model/Resolver/CategoryTree.php | 91 +++------ .../Products/DataProvider/CategoryTree.php | 186 ++++++++++++++++++ .../CustomAttributesFlatternizer.php | 45 +++++ .../Products/DataProvider/Product.php | 29 --- .../Products/FilterArgument/AstConverter.php | 1 + app/code/Magento/CatalogGraphQl/etc/di.xml | 1 + .../Magento/CatalogGraphQl/etc/graphql.xml | 21 +- .../Entity/Collection/AbstractCollection.php | 11 ++ app/code/Magento/EavGraphQl/etc/graphql.xml | 6 + .../Argument/AstConverterInterface.php | 2 +- .../GraphQl/Config/Common/Reader.php | 2 +- 18 files changed, 568 insertions(+), 266 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/CategoryInterfaceTypeResolver.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Config/CategoryAttributeReader.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Filter.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Search.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Category.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CustomAttributesFlatternizer.php diff --git a/app/code/Magento/Catalog/Model/ResourceModel/CategoryProduct.php b/app/code/Magento/Catalog/Model/ResourceModel/CategoryProduct.php index 9ff29faba8c05..5fbc2ddf94bb5 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/CategoryProduct.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/CategoryProduct.php @@ -29,47 +29,4 @@ protected function _construct() { $this->_init('catalog_category_product', 'entity_id'); } - - /** - * Retrieve distinct product ids, that are linked to categories - * - * @return array - */ - public function getDistinctProductIds() - { - $productIdsSelect = $this - ->getConnection() - ->select() - ->from($this->getTable('catalog_category_product'), 'product_id') - ->distinct('product_id'); - - return $this->getConnection()->fetchAll($productIdsSelect); - } - - /** - * Retrieve product ids grouped by categories - * - * @return array - */ - public function getProductsIdsGroupedByCategories() - { - $productIdsGroupedByCategories = []; - $productIdsSelect = $this - ->getConnection() - ->select() - ->from( - $this->getTable('catalog_category_product'), - ['category_id', 'product_id', 'position'] - ); - - $categoriesData = $this->getConnection()->fetchAll($productIdsSelect); - - foreach ($categoriesData as $categoryData) { - $categoryId = $categoryData['category_id']; - $productId = $categoryData['product_id']; - $productIdsGroupedByCategories[$categoryId][$productId] = $categoryData['position']; - } - - return $productIdsGroupedByCategories; - } } diff --git a/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php b/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php new file mode 100644 index 0000000000000..8aa6f585d6e23 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php @@ -0,0 +1,31 @@ +selectionSet->selections; + + /** @var FieldNode $field */ + foreach ($query as $field) { + if (!$collection->isAttributeAdded($field->name->value)) { + $collection->addAttributeToSelect($field->name->value); + } + } + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/CategoryInterfaceTypeResolver.php b/app/code/Magento/CatalogGraphQl/Model/CategoryInterfaceTypeResolver.php new file mode 100644 index 0000000000000..bf42c6b64ed17 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/CategoryInterfaceTypeResolver.php @@ -0,0 +1,25 @@ +mapper = $mapper; + $this->typeLocator = $typeLocator; + $this->collectionFactory = $collectionFactory; + } + + /** + * Read configuration scope + * + * @param string|null $scope + * @return array + * @throws GraphQlInputException + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function read($scope = null) + { + $config =[]; + $data = []; + /** @var Collection $collection */ + $collection = $this->collectionFactory->create(); + /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */ + foreach ($collection as $attribute) { + $attributeCode = $attribute->getAttributeCode(); + + if (in_array($attributeCode, self::$bannedSystemAttributes)) { + continue; + } + + $locatedType = $this->typeLocator->getType( + $attributeCode, + 'catalog_category' + ) ?: 'String'; + $locatedType = $locatedType === TypeProcessor::NORMALIZED_ANY_TYPE ? 'String' : ucfirst($locatedType); + $data['fields'][$attributeCode]['name'] = $attributeCode; + $data['fields'][$attributeCode]['type'] = $locatedType; + $data['fields'][$attributeCode]['arguments'] = []; + } + + $config['CategoryInterface'] = $data; + $config['CategoryTree'] = $data; + + return $config; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Filter.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Filter.php deleted file mode 100644 index dcc87b733d9c4..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Filter.php +++ /dev/null @@ -1,71 +0,0 @@ -searchCriteriaBuilder = $searchCriteriaBuilder; - $this->formatter = $formatter; - $this->categoryManagement = $categoryManagement; - $this->dataObjectProcessor = $dataObjectProcessor; - } - - /** - * Filter catalog product data based off given search criteria - * - * @param SearchCriteriaInterface $searchCriteria - * @return array - */ - public function getResult(SearchCriteriaInterface $searchCriteria) : array - { - $categoriesTree = $this->categoryManagement->getTree(2); - $categoriesTreeOutput = $this->dataObjectProcessor - ->buildOutputDataArray($categoriesTree, CategoryTreeInterface::class); - return $categoriesTreeOutput; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Search.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Search.php deleted file mode 100644 index 660071d9c4a42..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories/Query/Search.php +++ /dev/null @@ -1,52 +0,0 @@ -search = $search; - } - - /** - * Return results of full text catalog search of given term, and will return filtered results if filter is specified - * - * @param SearchCriteriaInterface $searchCriteria - * @return SearchResult - */ - public function getResult(SearchCriteriaInterface $searchCriteria) - { - $realPageSize = $searchCriteria->getPageSize(); - $realCurrentPage = $searchCriteria->getCurrentPage(); - // Current page must be set to 0 and page size to max for search to grab all ID's as temporary workaround - // for MAGETWO-85611 - $searchCriteria->setPageSize(PHP_INT_MAX); - $searchCriteria->setCurrentPage(0); - $searchResult = $this->search->search($searchCriteria); - $searchCriteria->setPageSize($realPageSize); - $searchCriteria->setCurrentPage($realCurrentPage); - return $this->searchResultFactory->create($searchResult->getTotalCount(), $searchResult->getItems()); - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category.php new file mode 100644 index 0000000000000..8f76b6c032040 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category.php @@ -0,0 +1,115 @@ +collection = $collectionFactory->create(); + $this->dataObjectProcessor = $dataObjectProcessor; + $this->attributesJoiner = $attributesJoiner; + $this->customAttributesFlatternizer = $customAttributesFlatternizer; + } + + /** + * @param Field $field + * @param array|null $value + * @param array|null $args + * @param $context + * @param ResolveInfo $info + * @return mixed + */ + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) + { + $this->categoryIds = array_merge($this->categoryIds, $value[self::PRODUCT_CATEGORY_IDS_KEY]); + $that = $this; + + return new Deferred(function () use ($that, $value, $info) { + $categories = []; + if (empty($that->categoryIds)) { + return []; + } + + if (!$this->collection->isLoaded()) { + $that->attributesJoiner->join($info->fieldASTs[0], $this->collection); + $this->collection->addIdFilter($this->categoryIds); + } + /** @var CategoryInterface | \Magento\Catalog\Model\Category $item */ + foreach ($this->collection as $item) { + if (in_array($item->getId(), $value[$that::PRODUCT_CATEGORY_IDS_KEY])) { + $categories[$item->getId()] = $this->dataObjectProcessor->buildOutputDataArray( + $item, + CategoryInterface::class + ); + $categories[$item->getId()] = $this->customAttributesFlatternizer + ->flaternize($categories[$item->getId()]); + $categories[$item->getId()]['product_count'] = $item->getProductCount(); + } + } + + return $categories; + }); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php index be5fd746bb7bf..2893e4e15a1ff 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php @@ -6,62 +6,49 @@ namespace Magento\CatalogGraphQl\Model\Resolver; -use GraphQL\Deferred; use GraphQL\Type\Definition\ResolveInfo; -use Magento\CatalogGraphQl\Model\Resolver\Categories\Query\Filter; use Magento\Framework\GraphQl\Config\Data\Field; -use Magento\Framework\GraphQl\Promise; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Resolver\ResolverInterface; -use Magento\Framework\GraphQl\Argument\SearchCriteria\Builder; -use Magento\CatalogGraphQl\Model\Resolver\Categories\Query\Search; /** - * Products field resolver, used for GraphQL request processing. + * Category tree field resolver, used for GraphQL request processing. */ class CategoryTree implements ResolverInterface { /** - * Category Tree key in graphql + * Name of type in GraphQL */ - const CATEGORY_TREE_KEY = 'children'; + const CATEGORY_INTERFACE = 'CategoryInterface'; /** - * @var Builder + * @var Products\DataProvider\CategoryTree */ - private $searchCriteriaBuilder; + private $categoryTree; /** - * @var Search + * @param Products\DataProvider\CategoryTree $categoryTree */ - private $categoriesSearch; - - /** - * @var Filter - */ - private $categoriesFilter; + public function __construct( + \Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CategoryTree $categoryTree + ) { + $this->categoryTree = $categoryTree; + } /** - * @var Products\DataProvider\Product + * Assert that filters from search criteria are valid and retrieve root category id + * + * @param array $args + * @return int + * @throws GraphQlInputException */ - private $productDataProvider; + private function assertFiltersAreValidAndGetCategoryRootIds(array $args) : int + { + if (!isset($args['filter']['root_category_id'])) { + throw new GraphQlInputException(__('"root_category_id" filter should be specified')); + } - /** - * CategoryTree constructor. - * @param Builder $searchCriteriaBuilder - * @param Search $categoriesSearch - * @param Filter $categoriesFilter - * @param Products\DataProvider\Product $productDataProvider - */ - public function __construct( - Builder $searchCriteriaBuilder, - Search $categoriesSearch, - Filter $categoriesFilter, - Products\DataProvider\Product $productDataProvider - ) { - $this->searchCriteriaBuilder = $searchCriteriaBuilder; - $this->categoriesSearch = $categoriesSearch; - $this->categoriesFilter = $categoriesFilter; - $this->productDataProvider = $productDataProvider; + return (int) $args['filter']['root_category_id']; } /** @@ -78,34 +65,8 @@ public function resolve(Field $field, array $value = null, array $args = null, $ return $value[$field->getName()]; } - $searchCriteria = $this->searchCriteriaBuilder->build($args); - - if (isset($args['search'])) { - $categoriesTree = $this->categoriesSearch->getResult($searchCriteria); - } else { - $categoriesTree = $this->categoriesFilter->getResult($searchCriteria); - } - - $processedCategoryTree = $this->processCategoriesTree([$categoriesTree]); - return ['category_tree' => $processedCategoryTree]; - } - - /** - * @param array $categoriesTree - * @return array - */ - private function processCategoriesTree(array $categoriesTree) - { - foreach ($categoriesTree as $nodeKey => $node) { - if (isset($node['children_data'])) { - $categoriesTree[$nodeKey][self::CATEGORY_TREE_KEY] = $this->processCategoriesTree($node['children_data']); - unset($categoriesTree[$nodeKey]['children_data']); - } - - $categoryProducts = $this->productDataProvider->getListOfProductsInCategories($node['id']); - $categoriesTree[$nodeKey]['products']['items'] = $categoryProducts; - } - - return $categoriesTree; + $rootCategoryId = $this->assertFiltersAreValidAndGetCategoryRootIds($args); + $categoriesTree = $this->categoryTree->getTree($info, $rootCategoryId); + return ['category_tree' => $categoriesTree]; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php new file mode 100644 index 0000000000000..539fcfb2cffa1 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php @@ -0,0 +1,186 @@ +collectionFactory = $collectionFactory; + $this->attributesJoiner = $attributesJoiner; + $this->resourceConnection = $resourceConnection; + $this->resourceCategory = $resourceCategory; + $this->customAttributesFlatternizer = $customAttributesFlatternizer; + $this->dataObjectProcessor = $dataObjectProcessor; + } + + /** + * @param ResolveInfo $resolveInfo + * @param int $rootCategoryId + * @return array + */ + public function getTree(ResolveInfo $resolveInfo, int $rootCategoryId) + { + $categoryQuery = $resolveInfo->fieldASTs[0]; + $collection = $this->collectionFactory->create(); + $this->joinAttributesRecursively($collection, $categoryQuery); + $depth = $this->calculateDepth($categoryQuery); + $level = $this->getLevelByRootCategoryId($rootCategoryId); + //Search for desired part of category tree + $collection->addFieldToFilter('level', ['gt' => $level]); + $collection->addFieldToFilter('level', ['lteq' => $level + $depth - self::DEPTH_OFFSET]); + $collection->setOrder('level'); + $collection->getSelect()->orWhere($this->resourceCategory->getLinkField() . ' = ?', $rootCategoryId); + return $this->processTree($collection->getIterator()); + } + + /** + * @param \Iterator $iterator + * @return array + */ + private function processTree(\Iterator $iterator) + { + $tree = []; + while ($iterator->valid()) { + /** @var CategoryInterface $category */ + $category = $iterator->current(); + $iterator->next(); + $nextCategory = $iterator->current(); + $tree[$category->getId()] = $this->hydrateCategory($category); + if ($nextCategory && (int) $nextCategory->getLevel() !== (int) $category->getLevel()) { + $tree[$category->getId()]['children'] = $this->processTree($iterator); + } + } + + return $tree; + } + + /** + * Hydrate and flaternize category object to flat array + * + * @param CategoryInterface $category + * @return array + */ + private function hydrateCategory(CategoryInterface $category) + { + $categoryData = $this->dataObjectProcessor->buildOutputDataArray($category, CategoryInterface::class); + $categoryData['id'] = $category->getId(); + $categoryData['product_count'] = $category->getProductCount(); + $categoryData['all_children'] = $category->getAllChildren(); + $categoryData['children'] = []; + return $this->customAttributesFlatternizer->flaternize($categoryData); + } + + /** + * @param int $rootCategoryId + * @return int + */ + private function getLevelByRootCategoryId(int $rootCategoryId) : int + { + $connection = $this->resourceConnection->getConnection(); + $select = $connection->select() + ->from($connection->getTableName('catalog_category_entity'), 'level') + ->where($this->resourceCategory->getLinkField() . " = ?", $rootCategoryId); + return (int) $connection->fetchOne($select); + } + + /** + * @param Collection $collection + * @param FieldNode $fieldNode + * @return void + */ + private function joinAttributesRecursively(Collection $collection, FieldNode $fieldNode) + { + if (!isset($fieldNode->selectionSet->selections)) { + return; + } + + $subSelection = $fieldNode->selectionSet->selections; + $this->attributesJoiner->join($fieldNode, $collection); + + /** @var FieldNode $node */ + foreach ($subSelection as $node) { + $this->joinAttributesRecursively($collection, $node); + } + } + + /** + * @param FieldNode $fieldNode + * @return int + */ + private function calculateDepth(FieldNode $fieldNode) : int + { + $selections = $fieldNode->selectionSet->selections ?? []; + $depth = count($selections) ? 1 : 0; + $childrenDepth = [0]; + foreach ($selections as $node) { + $childrenDepth[] = $this->calculateDepth($node); + } + + return $depth + max($childrenDepth); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CustomAttributesFlatternizer.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CustomAttributesFlatternizer.php new file mode 100644 index 0000000000000..d7eb4732c3e96 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CustomAttributesFlatternizer.php @@ -0,0 +1,45 @@ +setTotalCount($collection->getSize()); return $searchResult; } - - /** - * Retrieve products list by category ids - * - * @param $categoryId - * @return array - */ - public function getListOfProductsInCategories($categoryId) - { - if ($this->productsByCategories === null) { - $searchCriteria = $this->searchCriteriaBuilder->addFilter( - 'entity_id', - $this->categoryProduct->getDistinctProductIds(), - 'in' - ) - ->create(); - - $this->productsByCategories = $this->getList($searchCriteria)->getItems(); - } - - $productsByCategories = $this->categoryProduct->getProductsIdsGroupedByCategories(); - $productIds = $productsByCategories[$categoryId] ?? []; - return array_intersect_key($this->productsByCategories, array_keys($productIds)); - } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php index 868a95b491c88..0691be207667d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php @@ -45,6 +45,7 @@ class AstConverter implements AstConverterInterface * @var ConfigInterface */ private $config; + /** * @var array */ diff --git a/app/code/Magento/CatalogGraphQl/etc/di.xml b/app/code/Magento/CatalogGraphQl/etc/di.xml index b7338139e5b9f..e4e25c937d57c 100644 --- a/app/code/Magento/CatalogGraphQl/etc/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/di.xml @@ -24,6 +24,7 @@ Magento\CatalogGraphQl\Model\Config\AttributeReader + Magento\CatalogGraphQl\Model\Config\CategoryAttributeReader diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql.xml b/app/code/Magento/CatalogGraphQl/etc/graphql.xml index ee1c05b8a4089..dde57b4a27892 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql.xml @@ -12,7 +12,9 @@ - + + + AFN @@ -272,18 +274,26 @@ + + + + + + + + + + + - - - @@ -305,6 +315,9 @@ + + + diff --git a/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php b/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php index 76e7c7655ba84..1b51c01606448 100644 --- a/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php +++ b/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php @@ -1591,6 +1591,17 @@ protected function _reset() return $this; } + /** + * Check whether attribute with code is already added to collection + * + * @param string $attributeCode + * @return bool + */ + public function isAttributeAdded($attributeCode) + { + return isset($this->_selectAttributes[$attributeCode]); + } + /** * Returns already loaded element ids * diff --git a/app/code/Magento/EavGraphQl/etc/graphql.xml b/app/code/Magento/EavGraphQl/etc/graphql.xml index 4f71a4fa89985..acefa14a52f70 100644 --- a/app/code/Magento/EavGraphQl/etc/graphql.xml +++ b/app/code/Magento/EavGraphQl/etc/graphql.xml @@ -9,6 +9,12 @@ + + + + + + diff --git a/lib/internal/Magento/Framework/GraphQl/Argument/AstConverterInterface.php b/lib/internal/Magento/Framework/GraphQl/Argument/AstConverterInterface.php index 21a945593bda1..92cc80039a430 100644 --- a/lib/internal/Magento/Framework/GraphQl/Argument/AstConverterInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Argument/AstConverterInterface.php @@ -18,4 +18,4 @@ interface AstConverterInterface * @return Connective */ public function convert(string $entityType, $arguments); -} \ No newline at end of file +} diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php b/lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php index c9c9217d1b579..911265b66c7e6 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php @@ -37,7 +37,7 @@ public function read($scope = null) { $output = []; foreach ($this->readers as $reader) { - $output = array_merge_recursive($output, $reader->read($scope)); + $output = array_replace_recursive($output, $reader->read($scope)); } return $output; } From 54b79101a987aac23d4c87663e4c32ec2eebc036 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko Date: Tue, 27 Mar 2018 14:01:38 +0300 Subject: [PATCH 247/668] Merge branch 'MAGETWO-89031-graphql-strict-types' of https://github.com/magento-honey-badgers/magento2ce into MAGETWO-86939 # Conflicts: # app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php # app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php # app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/AstConverter.php # lib/internal/Magento/Framework/GraphQl/Argument/AstConverterInterface.php # lib/internal/Magento/Framework/GraphQl/Type/Output/ElementMapper/Formatter/Fields.php --- .../Model/CategoryInterfaceTypeResolver.php | 3 +- .../Model/Resolver/Category.php | 18 ++++++++--- .../Model/Resolver/CategoryTree.php | 32 ++++++++++++++----- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/CategoryInterfaceTypeResolver.php b/app/code/Magento/CatalogGraphQl/Model/CategoryInterfaceTypeResolver.php index bf42c6b64ed17..c1f3475929b29 100644 --- a/app/code/Magento/CatalogGraphQl/Model/CategoryInterfaceTypeResolver.php +++ b/app/code/Magento/CatalogGraphQl/Model/CategoryInterfaceTypeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model; @@ -18,7 +19,7 @@ class CategoryInterfaceTypeResolver implements TypeResolverInterface * {@inheritdoc} * @throws GraphQlInputException */ - public function resolveType(array $data) + public function resolveType(array $data) : string { return 'CategoryTree'; } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category.php index 8f76b6c032040..377a548c9479b 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category.php @@ -3,10 +3,10 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types = 1); namespace Magento\CatalogGraphQl\Model\Resolver; -use GraphQL\Deferred; use GraphQL\Type\Definition\ResolveInfo; use Magento\Catalog\Api\Data\CategoryInterface; use Magento\Catalog\Model\ResourceModel\Category\Collection; @@ -15,6 +15,8 @@ use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CustomAttributesFlatternizer; use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; use Magento\Framework\Reflection\DataObjectProcessor; /** @@ -54,23 +56,31 @@ class Category implements ResolverInterface */ private $customAttributesFlatternizer; + /** + * @var ValueFactory + */ + private $valueFactory; + /** * Category constructor. * @param CollectionFactory $collectionFactory * @param DataObjectProcessor $dataObjectProcessor * @param AttributesJoiner $attributesJoiner * @param CustomAttributesFlatternizer $customAttributesFlatternizer + * @param ValueFactory $valueFactory */ public function __construct( CollectionFactory $collectionFactory, DataObjectProcessor $dataObjectProcessor, AttributesJoiner $attributesJoiner, - CustomAttributesFlatternizer $customAttributesFlatternizer + CustomAttributesFlatternizer $customAttributesFlatternizer, + ValueFactory $valueFactory ) { $this->collection = $collectionFactory->create(); $this->dataObjectProcessor = $dataObjectProcessor; $this->attributesJoiner = $attributesJoiner; $this->customAttributesFlatternizer = $customAttributesFlatternizer; + $this->valueFactory = $valueFactory; } /** @@ -81,12 +91,12 @@ public function __construct( * @param ResolveInfo $info * @return mixed */ - public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info): ?Value { $this->categoryIds = array_merge($this->categoryIds, $value[self::PRODUCT_CATEGORY_IDS_KEY]); $that = $this; - return new Deferred(function () use ($that, $value, $info) { + return $this->valueFactory->create(function () use ($that, $value, $info) { $categories = []; if (empty($that->categoryIds)) { return []; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php index 2893e4e15a1ff..aab2d021047c5 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php @@ -10,6 +10,8 @@ use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Resolver\ResolverInterface; +use Magento\Framework\GraphQl\Resolver\Value; +use Magento\Framework\GraphQl\Resolver\ValueFactory; /** * Category tree field resolver, used for GraphQL request processing. @@ -26,13 +28,21 @@ class CategoryTree implements ResolverInterface */ private $categoryTree; + /** + * @var ValueFactory + */ + private $valueFactory; + /** * @param Products\DataProvider\CategoryTree $categoryTree + * @param ValueFactory $valueFactory */ public function __construct( - \Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CategoryTree $categoryTree + \Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CategoryTree $categoryTree, + ValueFactory $valueFactory ) { $this->categoryTree = $categoryTree; + $this->valueFactory = $valueFactory; } /** @@ -59,14 +69,20 @@ private function assertFiltersAreValidAndGetCategoryRootIds(array $args) : int * @param ResolveInfo $info * @return mixed */ - public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) + public function resolve(Field $field, array $value = null, array $args = null, $context, ResolveInfo $info) : ?Value { - if (isset($value[$field->getName()])) { - return $value[$field->getName()]; - } + $that = $this; + + return $this->valueFactory->create(function () use ($value, $args, $that, $field, $info) { + if (isset($value[$field->getName()])) { + return $value[$field->getName()]; + } - $rootCategoryId = $this->assertFiltersAreValidAndGetCategoryRootIds($args); - $categoriesTree = $this->categoryTree->getTree($info, $rootCategoryId); - return ['category_tree' => $categoriesTree]; + $rootCategoryId = $this->assertFiltersAreValidAndGetCategoryRootIds($args); + $categoriesTree = $this->categoryTree->getTree($info, $rootCategoryId); + return [ + 'category_tree' => $categoriesTree + ]; + }); } } From 62797ce4ea6a64b944ae3815e0705da85686c83c Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" Date: Tue, 27 Mar 2018 14:39:03 +0300 Subject: [PATCH 248/668] refactoring Operation and Bulk statuses interfaces, remove illogical interfaces and methods --- ...yInterface.php => BulkStatusInterface.php} | 17 +++-- .../Api/Data/BulkStatus/DetailedInterface.php | 58 --------------- .../Api/Data/BulkStatus/ShortInterface.php | 58 --------------- .../Api/Data/BulkStatusInterface.php | 34 +++++++++ .../Api/Data/DetailedBulkStatusInterface.php | 34 +++++++++ .../Api/Data/OperationDetailsInterface.php | 72 ------------------- .../OperationStatus/DetailedInterface.php | 70 ------------------ ...rface.php => OperationStatusInterface.php} | 9 +-- .../Model/BulkStatus.php | 66 ++++++----------- .../Model/Operation/Details.php | 5 +- .../Model/Operation/Status/Detailed.php | 66 ----------------- .../Status/Short.php => OperationStatus.php} | 6 +- .../Setup/UpgradeSchema.php | 58 --------------- .../Test/Unit/Model/BulkStatusTest.php | 23 ++---- .../AsynchronousOperations/etc/db_schema.xml | 2 + .../etc/db_schema_whitelist.json | 1 + .../Magento/AsynchronousOperations/etc/di.xml | 12 ++-- .../AsynchronousOperations/etc/webapi.xml | 15 ++-- 18 files changed, 133 insertions(+), 473 deletions(-) rename app/code/Magento/AsynchronousOperations/Api/{BulkRepositoryInterface.php => BulkStatusInterface.php} (56%) delete mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/DetailedInterface.php delete mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/ShortInterface.php create mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/BulkStatusInterface.php create mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/DetailedBulkStatusInterface.php delete mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/OperationDetailsInterface.php delete mode 100644 app/code/Magento/AsynchronousOperations/Api/Data/OperationStatus/DetailedInterface.php rename app/code/Magento/AsynchronousOperations/Api/Data/{OperationStatus/ShortInterface.php => OperationStatusInterface.php} (82%) delete mode 100644 app/code/Magento/AsynchronousOperations/Model/Operation/Status/Detailed.php rename app/code/Magento/AsynchronousOperations/Model/{Operation/Status/Short.php => OperationStatus.php} (79%) delete mode 100755 app/code/Magento/AsynchronousOperations/Setup/UpgradeSchema.php diff --git a/app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php b/app/code/Magento/AsynchronousOperations/Api/BulkStatusInterface.php similarity index 56% rename from app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php rename to app/code/Magento/AsynchronousOperations/Api/BulkStatusInterface.php index 5bfd07041e207..1c200f299f66f 100644 --- a/app/code/Magento/AsynchronousOperations/Api/BulkRepositoryInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/BulkStatusInterface.php @@ -7,25 +7,28 @@ namespace Magento\AsynchronousOperations\Api; /** + * Interface BulkStatusInterface + * Bulk summary data with list of operations items short data. + * * @api - * @since 100.3.0 */ -interface BulkRepositoryInterface +interface BulkStatusInterface extends \Magento\Framework\Bulk\BulkStatusInterface { - /** + * Get Bulk summary data with list of operations items full data. + * * @param string $bulkUuid - * @return \Magento\AsynchronousOperations\Api\Data\BulkStatus\DetailedInterface + * @return \Magento\AsynchronousOperations\Api\Data\DetailedBulkStatusInterface * @throws \Magento\Framework\Exception\NoSuchEntityException - * @since 100.3.0 */ public function getBulkDetailedStatus($bulkUuid); /** + * Get Bulk summary data with list of operations items short data. + * * @param string $bulkUuid - * @return \Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterface + * @return \Magento\AsynchronousOperations\Api\Data\BulkStatusInterface * @throws \Magento\Framework\Exception\NoSuchEntityException - * @since 100.3.0 */ public function getBulkShortStatus($bulkUuid); } diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/DetailedInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/DetailedInterface.php deleted file mode 100644 index 9bbc7fc621706..0000000000000 --- a/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatus/DetailedInterface.php +++ /dev/null @@ -1,58 +0,0 @@ -operationCollectionFactory = $operationCollection; @@ -103,7 +95,6 @@ public function __construct( $this->metadataPool = $metadataPool; $this->bulkDetailedFactory = $bulkDetailedFactory; $this->bulkShortFactory = $bulkShortFactory; - $this->operationCounterFactory = $operationCounter; $this->entityManager = $entityManager; } @@ -119,9 +110,9 @@ public function getFailedOperationsByBulkId($bulkUuid, $failureType = null) OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED, ]; $operations = $this->operationCollectionFactory->create() - ->addFieldToFilter('bulk_uuid', $bulkUuid) - ->addFieldToFilter('status', $failureCodes) - ->getItems(); + ->addFieldToFilter('bulk_uuid', $bulkUuid) + ->addFieldToFilter('status', $failureCodes) + ->getItems(); return $operations; } @@ -136,8 +127,8 @@ public function getOperationsCountByBulkIdAndStatus($bulkUuid, $status) $collection = $this->operationCollectionFactory->create(); return $collection->addFieldToFilter('bulk_uuid', $bulkUuid) - ->addFieldToFilter('status', $status) - ->getSize(); + ->addFieldToFilter('status', $status) + ->getSize(); } /** @@ -157,13 +148,13 @@ public function getBulksByUser($userId) ]; $select = $collection->getSelect(); $select->columns(['status' => $this->calculatedStatusSql->get($operationTableName)]) - ->order( - new \Zend_Db_Expr( - 'FIELD(status, ' . implode(',', $statusesArray) . ')' - ) - ); + ->order( + new \Zend_Db_Expr( + 'FIELD(status, ' . implode(',', $statusesArray) . ')' + ) + ); $collection->addFieldToFilter('user_id', $userId) - ->addOrder('start_time'); + ->addOrder('start_time'); return $collection->getItems(); } @@ -177,8 +168,8 @@ public function getBulkStatus($bulkUuid) * Number of operations that has been processed (i.e. operations with any status but 'open') */ $allProcessedOperationsQty = (int)$this->operationCollectionFactory->create() - ->addFieldToFilter('bulk_uuid', $bulkUuid) - ->getSize(); + ->addFieldToFilter('bulk_uuid', $bulkUuid) + ->getSize(); if ($allProcessedOperationsQty == 0) { return BulkSummaryInterface::NOT_STARTED; @@ -230,8 +221,8 @@ private function getOperationCount($bulkUuid) return (int)$connection->fetchOne( $connection->select() - ->from($metadata->getEntityTable(), 'operation_count') - ->where('uuid = ?', $bulkUuid) + ->from($metadata->getEntityTable(), 'operation_count') + ->where('uuid = ?', $bulkUuid) ); } @@ -253,14 +244,8 @@ public function getBulkDetailedStatus($bulkUuid) ) ); } - $operations = $this->operationCollectionFactory->create()->addFieldToFilter('bulk_uuid', $bulkUuid)->getItems(); - - /** @var \Magento\AsynchronousOperations\Model\Operation\Details $operationDetails */ - $operationCounter = $this->operationCounterFactory->create(['bulkUuid' => $bulkUuid]); - $bulk->setOperationsList($operations); - $bulk->setOperationsCounter($operationCounter); return $bulk; } @@ -274,7 +259,6 @@ public function getBulkShortStatus($bulkUuid) /** @var \Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterface $bulk */ $bulk = $this->entityManager->load($bulkSummary, $bulkUuid); - if ($bulk->getBulkId() === null) { throw new NoSuchEntityException( __( @@ -283,14 +267,8 @@ public function getBulkShortStatus($bulkUuid) ) ); } - $operations = $this->operationCollectionFactory->create()->addFieldToFilter('bulk_uuid', $bulkUuid)->getItems(); - - /** @var \Magento\AsynchronousOperations\Model\Operation\Details $operationDetails */ - $operationCounter = $this->operationCounterFactory->create(['bulkUuid' => $bulkUuid]); - $bulk->setOperationsList($operations); - $bulk->setOperationsCounter($operationCounter); return $bulk; } diff --git a/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php b/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php index 1dfd2cf45771d..d248f9c3e9276 100644 --- a/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php +++ b/app/code/Magento/AsynchronousOperations/Model/Operation/Details.php @@ -6,11 +6,10 @@ namespace Magento\AsynchronousOperations\Model\Operation; -use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface; use Magento\Framework\Bulk\OperationInterface; use Magento\Framework\Bulk\BulkStatusInterface; -class Details implements OperationDetailsInterface +class Details { /** * @var array @@ -95,6 +94,7 @@ public function getDetails($bulkUuid) public function getOperationsTotal() { $this->getDetails($this->bulkUuid); + return $this->operationCache[$this->bulkUuid]['operations_total']; } @@ -126,6 +126,7 @@ public function getOperationsSuccessful() public function getTotalFailed() { $this->getDetails($this->bulkUuid); + return $this->operationCache[$this->bulkUuid]['operations_failed']; } diff --git a/app/code/Magento/AsynchronousOperations/Model/Operation/Status/Detailed.php b/app/code/Magento/AsynchronousOperations/Model/Operation/Status/Detailed.php deleted file mode 100644 index f054c6d56fc73..0000000000000 --- a/app/code/Magento/AsynchronousOperations/Model/Operation/Status/Detailed.php +++ /dev/null @@ -1,66 +0,0 @@ -getData(OperationInterface::ID); - } - - /** - * @inheritDoc - */ - public function getTopicName() - { - return $this->getData(OperationInterface::TOPIC_NAME); - } - - /** - * @inheritDoc - */ - public function getStatus() - { - return $this->getData(OperationInterface::STATUS); - } - - /** - * @inheritDoc - */ - public function getResultSerializedData() - { - return $this->getData(OperationInterface::RESULT_SERIALIZED_DATA); - } - - /** - * @inheritDoc - */ - public function getResultMessage() - { - return $this->getData(OperationInterface::RESULT_MESSAGE); - } - - /** - * @inheritDoc - */ - public function getErrorCode() - { - return $this->getData(OperationInterface::ERROR_CODE); - } -} diff --git a/app/code/Magento/AsynchronousOperations/Model/Operation/Status/Short.php b/app/code/Magento/AsynchronousOperations/Model/OperationStatus.php similarity index 79% rename from app/code/Magento/AsynchronousOperations/Model/Operation/Status/Short.php rename to app/code/Magento/AsynchronousOperations/Model/OperationStatus.php index 3d4952748dd44..6af12b9ba2518 100644 --- a/app/code/Magento/AsynchronousOperations/Model/Operation/Status/Short.php +++ b/app/code/Magento/AsynchronousOperations/Model/OperationStatus.php @@ -4,17 +4,17 @@ * See COPYING.txt for license details. */ -namespace Magento\AsynchronousOperations\Model\Operation\Status; +namespace Magento\AsynchronousOperations\Model; use Magento\AsynchronousOperations\Api\Data\OperationInterface; -use Magento\AsynchronousOperations\Api\Data\OperationStatus\ShortInterface; +use Magento\AsynchronousOperations\Api\Data\OperationStatusInterface; use Magento\Framework\DataObject; use Magento\Framework\Api\ExtensibleDataInterface; /** * Class OperationShortDetails */ -class Short extends DataObject implements ShortInterface, ExtensibleDataInterface +class OperationStatus extends DataObject implements OperationStatusInterface, ExtensibleDataInterface { /** * @inheritDoc diff --git a/app/code/Magento/AsynchronousOperations/Setup/UpgradeSchema.php b/app/code/Magento/AsynchronousOperations/Setup/UpgradeSchema.php deleted file mode 100755 index 21286538e70b2..0000000000000 --- a/app/code/Magento/AsynchronousOperations/Setup/UpgradeSchema.php +++ /dev/null @@ -1,58 +0,0 @@ -startSetup(); - if (version_compare($context->getVersion(), '2.0.1', '<')) { - $this->addResultSerializedDataColumn($setup); - } - - $setup->endSetup(); - } - - /** - * Add the column 'result_serialized_data' to the Bulk Operation table. - * - * @param SchemaSetupInterface $setup - * @return void - */ - private function addResultSerializedDataColumn(SchemaSetupInterface $setup) - { - $connection = $setup->getConnection(); - $tableName = $setup->getTable('magento_operation'); - if (!$connection->tableColumnExists($tableName, 'result_serialized_data')) { - $connection->addColumn( - $tableName, - 'result_serialized_data', - [ - 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_BLOB, - 'size' => 0, - 'nullable' => true, - 'comment' => 'Result data (serialized) after perform an operation', - ] - ); - } - } -} diff --git a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkStatusTest.php b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkStatusTest.php index 0f1096481c936..c32134fe29594 100644 --- a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkStatusTest.php +++ b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkStatusTest.php @@ -64,11 +64,6 @@ class BulkStatusTest extends \PHPUnit\Framework\TestCase */ private $bulkShortFactory; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $operationCounterFactory; - /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -102,15 +97,11 @@ protected function setUp() ); $this->metadataPoolMock = $this->createMock(\Magento\Framework\EntityManager\MetadataPool::class); $this->bulkDetailedFactory = $this->createPartialMock( - \Magento\AsynchronousOperations\Api\Data\BulkStatus\DetailedInterfaceFactory ::class, + \Magento\AsynchronousOperations\Api\Data\DetailedBulkStatusInterfaceFactory ::class, ['create'] ); $this->bulkShortFactory = $this->createPartialMock( - \Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterfaceFactory::class, - ['create'] - ); - $this->operationCounterFactory = $this->createPartialMock( - \Magento\AsynchronousOperations\Api\Data\OperationDetailsInterfaceFactory::class, + \Magento\AsynchronousOperations\Api\Data\BulkStatusInterfaceFactory::class, ['create'] ); $this->entityManager = $this->createMock(\Magento\Framework\EntityManager\EntityManager::class); @@ -126,7 +117,6 @@ protected function setUp() $this->metadataPoolMock, $this->bulkDetailedFactory, $this->bulkShortFactory, - $this->operationCounterFactory, $this->entityManager ); } @@ -188,12 +178,13 @@ public function getFailedOperationsByBulkIdDataProvider() { return [ [1, [1]], - [null, + [ + null, [ OperationInterface::STATUS_TYPE_RETRIABLY_FAILED, - OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED - ] - ] + OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED, + ], + ], ]; } diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml index b986b98abf3ad..1b99ce9a2805f 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml @@ -37,6 +37,8 @@ comment="Name of the related message queue topic"/> + - + - - - - - + + + @@ -81,6 +79,4 @@ - - diff --git a/app/code/Magento/AsynchronousOperations/etc/webapi.xml b/app/code/Magento/AsynchronousOperations/etc/webapi.xml index c2b6cd8d613c5..253dedd1c7a0c 100644 --- a/app/code/Magento/AsynchronousOperations/etc/webapi.xml +++ b/app/code/Magento/AsynchronousOperations/etc/webapi.xml @@ -8,15 +8,22 @@ - - + + - - + + + + + + + + + From 47b6cbc3ecb00fb1e242d5544bf1087619440828 Mon Sep 17 00:00:00 2001 From: Stas Kozar Date: Tue, 27 Mar 2018 14:40:07 +0300 Subject: [PATCH 249/668] MAGETWO-88177: Create Functional Test to verify if Ordered Products Grid displays child simple products SKU for a configurable product --- .../Test/Repository/ConfigurableProduct.xml | 69 +++++++++++++++++++ .../ConfigurableProduct/CheckoutData.xml | 21 ++++++ .../Block/Adminhtml/Product/Sold/Grid.php | 26 +++++++ ...redProductReportForConfigurableProduct.php | 58 ++++++++++++++++ .../OrderedProductsReportEntityTest.php | 1 - .../OrderedProductsReportEntityTest.xml | 8 +++ .../Sales/Test/Repository/OrderInjectable.xml | 24 +++++++ 7 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertOrderedProductReportForConfigurableProduct.php diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml index 25fa0e6ec07d2..a524139d3f3ad 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml @@ -1115,5 +1115,74 @@ + + Configurable product with sizes %isolation% + sku_configurable_product_with_sizes_%isolation% + This item has weight + 2 + Yes + Catalog, Search + + taxable_goods + + configurable-product-with-size-%isolation% + + size_3_items + + + In Stock + + + + default + + + + default_anchor_subcategory + + + default + + + 170 + + + + + Configurable product with two options %isolation% + sku_test_configurable_product_with_two_options_%isolation% + + 40 + price_40 + + This item has weight + 30 + Yes + Catalog, Search + + taxable_goods + + configurable-product-with-two-options-%isolation% + + two_options + + + In Stock + + + + default + + + + default + + + configurable_default_with_two_options + + + default_subcategory + + diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml index 003c129c9f969..136696ff81047 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml @@ -466,5 +466,26 @@ 15 + + + + + + attribute_key_0 + option_key_0 + + + attribute_key_0 + option_key_1 + + + + 3 + + 40 + 3 + 120 + + diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Sold/Grid.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Sold/Grid.php index f74fe80f69eb3..3f53c7d2126b5 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Sold/Grid.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Sold/Grid.php @@ -34,6 +34,13 @@ class Grid extends \Magento\Backend\Test\Block\Widget\Grid */ protected $product = './/*[contains(.,"%s")]/*[contains(@class,"col-qty")]'; + /** + * Product sku from grid locator + * + * @var string + */ + private $productSku = './/*[contains(.,"%s")]/*[contains(@class,"col-sku")]'; + /** * Filter locator * @@ -102,4 +109,23 @@ public function getOrdersResults(OrderInjectable $order) } return $views; } + + /** + * Get product sku from Ordered Products Report grid. + * + * @param OrderInjectable $order + * @return array + */ + public function getOrdersResultsforConfigurableProducts(OrderInjectable $order) + { + $products = $order->getEntityId()['products']; + $skus = []; + + foreach ($products as $key => $productSku) { + $skus[$key] = $this->_rootElement + ->find(sprintf($this->productSku, $productSku->getName()), Locator::SELECTOR_XPATH)->getText(); + } + + return $skus; + } } diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertOrderedProductReportForConfigurableProduct.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertOrderedProductReportForConfigurableProduct.php new file mode 100644 index 0000000000000..f89df176e475a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertOrderedProductReportForConfigurableProduct.php @@ -0,0 +1,58 @@ +getEntityId()['products']; + $simpleChildSku = $orderedProducts->getGridBlock()->getOrdersResultsforConfigurableProducts($order); + $filters = []; + foreach ($products as $product) { + /** @var ConfigurableProduct $product */ + if ($product->hasData('configurable_attributes_data')) { + $matrix = isset($product->getConfigurableAttributesData()['matrix']) ? + $product->getConfigurableAttributesData()['matrix'] : []; + foreach ($matrix as $variation) { + $filters[] = $variation['sku']; + } + } + } + + \PHPUnit\Framework\Assert::assertContains( + $simpleChildSku[0], + $filters, + 'Ordered simple product sku is not present in the Reports grid' + ); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Child product sku is present on the Ordered Products report grid'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php index 570cbb5ba8f16..b43eb335d36c5 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php @@ -28,7 +28,6 @@ class OrderedProductsReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.xml index a6b325e19d29c..15947020c1bbe 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.xml @@ -28,5 +28,13 @@ Day + + configurable_product + m/d/Y -1 day + m/d/Y + Day + + + diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable.xml index aff22086394d2..e6c61c189d195 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable.xml @@ -326,5 +326,29 @@ 0 USD + + + + configurableProduct::with_only_two_options + + + default + + + US_address + + + default_store_view + + + checkmo + + flatrate_flatrate + + free + + 0 + USD + From 5a373c172e831053d28f0449c332282405e06bf4 Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" Date: Tue, 27 Mar 2018 14:59:54 +0300 Subject: [PATCH 250/668] fix interface description --- .../AsynchronousOperations/Api/Data/BulkStatusInterface.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatusInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatusInterface.php index a78213d05b707..8a73a9e2a95ff 100644 --- a/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatusInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/Data/BulkStatusInterface.php @@ -8,7 +8,6 @@ /** * Interface BulkStatusInterface - * Bulk summary data with list of operations items short data. * * @api */ From 2973e4fc40729a7ec3b34cc827051278b42b18bb Mon Sep 17 00:00:00 2001 From: Eugene Tulika Date: Tue, 27 Mar 2018 07:56:28 -0500 Subject: [PATCH 251/668] magento-engcom/bulk-api#4 Support for Async operations in WebAPI - Moved MassSchedule class to Asynchronous operations --- .../Api/Data/AsyncResponseInterface.php | 20 ++++------- .../Api/Data/ItemStatusInterface.php | 12 +------ .../Model/AsyncResponse.php | 6 ++-- .../Model}/ItemStatus.php | 4 +-- .../Model}/MassConsumer.php | 2 +- .../Model}/MassPublisher.php | 2 +- .../Model}/MassSchedule.php | 15 ++++---- .../Magento/AsynchronousOperations/etc/di.xml | 27 ++++++++++++-- .../Rest/AsynchronousRequestProcessor.php | 23 ++++++------ app/code/Magento/WebapiAsync/Model/Config.php | 1 - .../WebapiAsync/Model/ConfigInterface.php | 17 ++++----- app/code/Magento/WebapiAsync/composer.json | 1 - app/code/Magento/WebapiAsync/etc/di.xml | 35 ------------------- .../WebapiAsync/etc/queue_consumer.xml | 2 +- .../Model}/MassScheduleTest.php | 3 +- 15 files changed, 67 insertions(+), 103 deletions(-) rename app/code/Magento/{WebapiAsync => AsynchronousOperations}/Api/Data/AsyncResponseInterface.php (68%) rename app/code/Magento/{WebapiAsync => AsynchronousOperations}/Api/Data/ItemStatusInterface.php (88%) rename app/code/Magento/{WebapiAsync => AsynchronousOperations}/Model/AsyncResponse.php (87%) rename app/code/Magento/{WebapiAsync/Model/AsyncResponse => AsynchronousOperations/Model}/ItemStatus.php (94%) rename app/code/Magento/{WebapiAsync/Model/MessageQueue => AsynchronousOperations/Model}/MassConsumer.php (99%) rename app/code/Magento/{WebapiAsync/Model/MessageQueue => AsynchronousOperations/Model}/MassPublisher.php (98%) rename app/code/Magento/{WebapiAsync/Model/MessageQueue => AsynchronousOperations/Model}/MassSchedule.php (93%) delete mode 100755 app/code/Magento/WebapiAsync/etc/di.xml rename dev/tests/integration/testsuite/Magento/{WebapiAsync/Model/MessageQueue => AsynchronousOperations/Model}/MassScheduleTest.php (98%) diff --git a/app/code/Magento/WebapiAsync/Api/Data/AsyncResponseInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/AsyncResponseInterface.php similarity index 68% rename from app/code/Magento/WebapiAsync/Api/Data/AsyncResponseInterface.php rename to app/code/Magento/AsynchronousOperations/Api/Data/AsyncResponseInterface.php index e9629316773d5..19f87c55ed60e 100644 --- a/app/code/Magento/WebapiAsync/Api/Data/AsyncResponseInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/Data/AsyncResponseInterface.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\WebapiAsync\Api\Data; +namespace Magento\AsynchronousOperations\Api\Data; /** * Interface AsyncResponseInterface @@ -22,7 +22,6 @@ interface AsyncResponseInterface * Gets the bulk uuid. * * @return string Bulk Uuid. - * @since 100.3.0 */ public function getBulkUuid(); @@ -31,30 +30,27 @@ public function getBulkUuid(); * * @param string $bulkUuid * @return $this - * @since 100.3.0 */ public function setBulkUuid($bulkUuid); /** * Gets the list of request items with status data. * - * @return \Magento\WebapiAsync\Api\Data\ItemStatusInterface[] - * @since 100.3.0 + * @return \Magento\AsynchronousOperations\Api\Data\ItemStatusInterface[] */ public function getRequestItems(); /** * Sets the list of request items with status data. * - * @param \Magento\WebapiAsync\Api\Data\ItemStatusInterface[] $requestItems + * @param \Magento\AsynchronousOperations\Api\Data\ItemStatusInterface[] $requestItems * @return $this - * @since 100.3.0 */ public function setRequestItems($requestItems); /** * @param bool $isErrors - * @return \Magento\WebapiAsync\Api\Data\AsyncResponseInterface + * @return $this */ public function setIsErrors($isErrors = false); @@ -68,19 +64,17 @@ public function getIsErrors(); /** * Retrieve existing extension attributes object. * - * @return \Magento\WebapiAsync\Api\Data\AsyncResponseExtensionInterface|null - * @since 100.3.0 + * @return \Magento\AsynchronousOperations\Api\Data\AsyncResponseExtensionInterface|null */ public function getExtensionAttributes(); /** * Set an extension attributes object. * - * @param \Magento\WebapiAsync\Api\Data\AsyncResponseExtensionInterface $extensionAttributes + * @param \Magento\AsynchronousOperations\Api\Data\AsyncResponseExtensionInterface $extensionAttributes * @return $this - * @since 100.3.0 */ public function setExtensionAttributes( - \Magento\WebapiAsync\Api\Data\AsyncResponseExtensionInterface $extensionAttributes + \Magento\AsynchronousOperations\Api\Data\AsyncResponseExtensionInterface $extensionAttributes ); } diff --git a/app/code/Magento/WebapiAsync/Api/Data/ItemStatusInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/ItemStatusInterface.php similarity index 88% rename from app/code/Magento/WebapiAsync/Api/Data/ItemStatusInterface.php rename to app/code/Magento/AsynchronousOperations/Api/Data/ItemStatusInterface.php index c9a863a0d2fae..82cbe1386c28c 100644 --- a/app/code/Magento/WebapiAsync/Api/Data/ItemStatusInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/Data/ItemStatusInterface.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\WebapiAsync\Api\Data; +namespace Magento\AsynchronousOperations\Api\Data; /** * ItemStatusInterface interface @@ -28,7 +28,6 @@ interface ItemStatusInterface * Get entity Id. * * @return int - * @since 100.3.0 */ public function getId(); @@ -37,7 +36,6 @@ public function getId(); * * @param int $entityId * @return $this - * @since 100.3.0 */ public function setId($entityId); @@ -45,7 +43,6 @@ public function setId($entityId); * Get hash of entity data. * * @return string md5 hash of entity params array. - * @since 100.3.0 */ public function getDataHash(); @@ -54,7 +51,6 @@ public function getDataHash(); * * @param string $hash md5 hash of entity params array. * @return $this - * @since 100.3.0 */ public function setDataHash($hash); @@ -62,7 +58,6 @@ public function setDataHash($hash); * Get status. * * @return string accepted|rejected - * @since 100.3.0 */ public function getStatus(); @@ -71,7 +66,6 @@ public function getStatus(); * * @param string $status accepted|rejected * @return $this - * @since 100.3.0 */ public function setStatus($status = self::STATUS_ACCEPTED); @@ -79,7 +73,6 @@ public function setStatus($status = self::STATUS_ACCEPTED); * Get error information. * * @return string|null - * @since 100.3.0 */ public function getErrorMessage(); @@ -88,7 +81,6 @@ public function getErrorMessage(); * * @param string|null|\Exception $error * @return $this - * @since 100.3.0 */ public function setErrorMessage($error = null); @@ -96,7 +88,6 @@ public function setErrorMessage($error = null); * Get error code. * * @return int|null - * @since 100.3.0 */ public function getErrorCode(); @@ -105,7 +96,6 @@ public function getErrorCode(); * * @param int|null|\Exception $errorCode Default: null * @return $this - * @since 100.3.0 */ public function setErrorCode($errorCode = null); } diff --git a/app/code/Magento/WebapiAsync/Model/AsyncResponse.php b/app/code/Magento/AsynchronousOperations/Model/AsyncResponse.php similarity index 87% rename from app/code/Magento/WebapiAsync/Model/AsyncResponse.php rename to app/code/Magento/AsynchronousOperations/Model/AsyncResponse.php index c4ac59ff4ba70..23447ddea82ba 100644 --- a/app/code/Magento/WebapiAsync/Model/AsyncResponse.php +++ b/app/code/Magento/AsynchronousOperations/Model/AsyncResponse.php @@ -4,9 +4,9 @@ * See COPYING.txt for license details. */ -namespace Magento\WebapiAsync\Model; +namespace Magento\AsynchronousOperations\Model; -use Magento\WebapiAsync\Api\Data\AsyncResponseInterface; +use Magento\AsynchronousOperations\Api\Data\AsyncResponseInterface; use Magento\Framework\DataObject; use Magento\Framework\Api\ExtensibleDataInterface; @@ -72,7 +72,7 @@ public function getExtensionAttributes() * @inheritDoc */ public function setExtensionAttributes( - \Magento\WebapiAsync\Api\Data\AsyncResponseExtensionInterface $extensionAttributes + \Magento\AsynchronousOperations\Api\Data\AsyncResponseExtensionInterface $extensionAttributes ) { return $this->setData(self::EXTENSION_ATTRIBUTES_KEY, $extensionAttributes); } diff --git a/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemStatus.php b/app/code/Magento/AsynchronousOperations/Model/ItemStatus.php similarity index 94% rename from app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemStatus.php rename to app/code/Magento/AsynchronousOperations/Model/ItemStatus.php index ab34561fcf049..0ea73fb3b1927 100644 --- a/app/code/Magento/WebapiAsync/Model/AsyncResponse/ItemStatus.php +++ b/app/code/Magento/AsynchronousOperations/Model/ItemStatus.php @@ -4,9 +4,9 @@ * See COPYING.txt for license details. */ -namespace Magento\WebapiAsync\Model\AsyncResponse; +namespace Magento\AsynchronousOperations\Model; -use Magento\WebapiAsync\Api\Data\ItemStatusInterface; +use Magento\AsynchronousOperations\Api\Data\ItemStatusInterface; use Magento\Framework\DataObject; class ItemStatus extends DataObject implements ItemStatusInterface diff --git a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassConsumer.php b/app/code/Magento/AsynchronousOperations/Model/MassConsumer.php similarity index 99% rename from app/code/Magento/WebapiAsync/Model/MessageQueue/MassConsumer.php rename to app/code/Magento/AsynchronousOperations/Model/MassConsumer.php index 9caeed6a0d0f8..65d978f048464 100644 --- a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassConsumer.php +++ b/app/code/Magento/AsynchronousOperations/Model/MassConsumer.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\WebapiAsync\Model\MessageQueue; +namespace Magento\AsynchronousOperations\Model; use Magento\Framework\App\ResourceConnection; use Psr\Log\LoggerInterface; diff --git a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassPublisher.php b/app/code/Magento/AsynchronousOperations/Model/MassPublisher.php similarity index 98% rename from app/code/Magento/WebapiAsync/Model/MessageQueue/MassPublisher.php rename to app/code/Magento/AsynchronousOperations/Model/MassPublisher.php index ffdf363ebdac9..608fd2acc7056 100644 --- a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassPublisher.php +++ b/app/code/Magento/AsynchronousOperations/Model/MassPublisher.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\WebapiAsync\Model\MessageQueue; +namespace Magento\AsynchronousOperations\Model; use Magento\Framework\MessageQueue\MessageValidator; use Magento\Framework\MessageQueue\MessageEncoder; diff --git a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php b/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php similarity index 93% rename from app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php rename to app/code/Magento/AsynchronousOperations/Model/MassSchedule.php index 3f0f163f61a89..cdb34fb6151ab 100644 --- a/app/code/Magento/WebapiAsync/Model/MessageQueue/MassSchedule.php +++ b/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php @@ -4,17 +4,17 @@ * See COPYING.txt for license details. */ -namespace Magento\WebapiAsync\Model\MessageQueue; +namespace Magento\AsynchronousOperations\Model; use Magento\AsynchronousOperations\Api\Data\OperationInterface; use Magento\AsynchronousOperations\Api\Data\OperationInterfaceFactory; use Magento\Framework\DataObject\IdentityGeneratorInterface; use Magento\Framework\EntityManager\EntityManager; use Magento\Framework\Exception\LocalizedException; -use Magento\WebapiAsync\Api\Data\ItemStatusInterfaceFactory; -use Magento\WebapiAsync\Api\Data\AsyncResponseInterface; -use Magento\WebapiAsync\Api\Data\AsyncResponseInterfaceFactory; -use Magento\WebapiAsync\Api\Data\ItemStatusInterface; +use Magento\AsynchronousOperations\Api\Data\ItemStatusInterfaceFactory; +use Magento\AsynchronousOperations\Api\Data\AsyncResponseInterface; +use Magento\AsynchronousOperations\Api\Data\AsyncResponseInterfaceFactory; +use Magento\AsynchronousOperations\Api\Data\ItemStatusInterface; use Magento\Framework\MessageQueue\MessageValidator; use Magento\Framework\MessageQueue\MessageEncoder; use Magento\Framework\Bulk\BulkManagementInterface; @@ -23,8 +23,7 @@ use Psr\Log\LoggerInterface; /** - * Class MassPublisher used for encoding topic entities to OperationInterface and publish them. - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * Class MassSchedule used for adding multiple entities as Operations to Bulk Management with the status tracking */ class MassSchedule { @@ -192,7 +191,7 @@ public function publishMass($topicName, array $entitiesArray, $groupId = null, $ __('Something went wrong while processing the request.') ); } - /** @var \Magento\WebapiAsync\Api\Data\AsyncResponseInterface $asyncResponse */ + /** @var AsyncResponseInterface $asyncResponse */ $asyncResponse = $this->asyncResponseFactory->create(); $asyncResponse->setBulkUuid($groupId); $asyncResponse->setRequestItems($requestItems); diff --git a/app/code/Magento/AsynchronousOperations/etc/di.xml b/app/code/Magento/AsynchronousOperations/etc/di.xml index 3a4225347eeb3..800e0e52aba10 100644 --- a/app/code/Magento/AsynchronousOperations/etc/di.xml +++ b/app/code/Magento/AsynchronousOperations/etc/di.xml @@ -74,6 +74,29 @@ - + + + + + + Magento\AsynchronousOperations\Model\MassPublisher + Magento\AsynchronousOperations\Model\MassPublisher + + + + + + + Magento\AsynchronousOperations\Model\VirtualType\PublisherPool + + + + + Magento\AsynchronousOperations\Model\VirtualType\BulkManagement + + + + diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php index 79d3856d50821..f1ac64f5bc720 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php @@ -10,10 +10,11 @@ use Magento\Webapi\Controller\Rest\RequestProcessorInterface; use Magento\Framework\Webapi\Rest\Response as RestResponse; use Magento\WebapiAsync\Controller\Rest\Async\InputParamsResolver; -use Magento\WebapiAsync\Model\MessageQueue\MassSchedule; +use Magento\AsynchronousOperations\Model\MassSchedule; use Magento\WebapiAsync\Model\ConfigInterface as WebApiAsyncConfig; use Magento\Framework\Reflection\DataObjectProcessor; -use Magento\WebapiAsync\Api\Data\AsyncResponseInterfaceFactory; +use Magento\AsynchronousOperations\Api\Data\AsyncResponseInterfaceFactory; +use Magento\AsynchronousOperations\Api\Data\AsyncResponseInterface; class AsynchronousRequestProcessor implements RequestProcessorInterface { @@ -30,7 +31,7 @@ class AsynchronousRequestProcessor implements RequestProcessorInterface private $inputParamsResolver; /** - * @var \Magento\WebapiAsync\Model\MessageQueue\MassSchedule + * @var MassSchedule */ private $asyncBulkPublisher; @@ -45,19 +46,19 @@ class AsynchronousRequestProcessor implements RequestProcessorInterface private $dataObjectProcessor; /** - * @var \Magento\WebapiAsync\Api\Data\AsyncResponseInterfaceFactory + * @var AsyncResponseInterfaceFactory */ private $asyncResponseFactory; /** * Initialize dependencies. * - * @param \Magento\Framework\Webapi\Rest\Response $response - * @param \Magento\WebapiAsync\Controller\Rest\Async\InputParamsResolver $inputParamsResolver - * @param \Magento\WebapiAsync\Model\MessageQueue\MassSchedule $asyncBulkPublisher - * @param \Magento\WebapiAsync\Model\ConfigInterface $webapiAsyncConfig - * @param \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor - * @param \Magento\WebapiAsync\Api\Data\AsyncResponseInterfaceFactory $asyncResponse + * @param RestResponse $response + * @param InputParamsResolver $inputParamsResolver + * @param MassSchedule $asyncBulkPublisher + * @param WebapiAsyncConfig $webapiAsyncConfig + * @param DataObjectProcessor $dataObjectProcessor + * @param AsyncResponseInterfaceFactory $asyncResponse */ public function __construct( RestResponse $response, @@ -101,7 +102,7 @@ public function process(\Magento\Framework\Webapi\Rest\Request $request) $responseData = $this->dataObjectProcessor->buildOutputDataArray( $asyncResponse, - \Magento\WebapiAsync\Api\Data\AsyncResponseInterface::class + AsyncResponseInterface::class ); $this->response->setStatusCode(RestResponse::STATUS_CODE_202) diff --git a/app/code/Magento/WebapiAsync/Model/Config.php b/app/code/Magento/WebapiAsync/Model/Config.php index 02c459b68c531..335d300393572 100644 --- a/app/code/Magento/WebapiAsync/Model/Config.php +++ b/app/code/Magento/WebapiAsync/Model/Config.php @@ -57,7 +57,6 @@ public function __construct( */ public function getServices() { - if (null === $this->asyncServices) { $services = $this->cache->load(self::CACHE_ID); if ($services && is_string($services)) { diff --git a/app/code/Magento/WebapiAsync/Model/ConfigInterface.php b/app/code/Magento/WebapiAsync/Model/ConfigInterface.php index 7a2683da71864..39a7991fda680 100644 --- a/app/code/Magento/WebapiAsync/Model/ConfigInterface.php +++ b/app/code/Magento/WebapiAsync/Model/ConfigInterface.php @@ -6,33 +6,29 @@ namespace Magento\WebapiAsync\Model; -use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Communication\ConfigInterface as CommunicationConfig; use Magento\AsynchronousOperations\Api\Data\OperationInterface; -use Magento\Framework\Communication\Config\ReflectionGenerator; +use Magento\AsynchronousOperations\Model\MassConsumer; /** * Class for accessing to Webapi_Async configuration. * * @api - * @since 100.3.0 */ interface ConfigInterface { + /**#@+ + * Constants for Webapi Asynchronous Config generation + */ const CACHE_ID = 'webapi_async_config'; - const TOPIC_PREFIX = 'async.'; - - const DEFAULT_CONSUMER_INSTANCE = \Magento\WebapiAsync\Model\MessageQueue\MassConsumer::class; + const DEFAULT_CONSUMER_INSTANCE = MassConsumer::class; const DEFAULT_CONSUMER_CONNECTION = 'amqp'; const DEFAULT_CONSUMER_MAX_MESSAGE = null; - const SERVICE_PARAM_KEY_INTERFACE = 'interface'; const SERVICE_PARAM_KEY_METHOD = 'method'; const SERVICE_PARAM_KEY_TOPIC = 'topic'; - const DEFAULT_HANDLER_NAME = 'async'; - const SYSTEM_TOPIC_NAME = 'async.system.required.wrapper.topic'; const SYSTEM_TOPIC_CONFIGURATION = [ CommunicationConfig::TOPIC_NAME => self::SYSTEM_TOPIC_NAME, @@ -42,12 +38,12 @@ interface ConfigInterface CommunicationConfig::TOPIC_RESPONSE => null, CommunicationConfig::TOPIC_HANDLERS => [], ]; + /**#@-*/ /** * Get array of generated topics name and related to this topic service class and methods * * @return array - * @since 100.3.0 */ public function getServices(); @@ -58,7 +54,6 @@ public function getServices(); * @param string $httpMethod GET|POST|PUT|DELETE * @return string * @throws \Magento\Framework\Exception\LocalizedException - * @since 100.3.0 */ public function getTopicName($routeUrl, $httpMethod); } diff --git a/app/code/Magento/WebapiAsync/composer.json b/app/code/Magento/WebapiAsync/composer.json index 1ceaaac86daf7..d4ee8e3f4c8f1 100644 --- a/app/code/Magento/WebapiAsync/composer.json +++ b/app/code/Magento/WebapiAsync/composer.json @@ -7,7 +7,6 @@ "require": { "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", "magento/framework": "100.3.*", - "magento/module-authorization": "100.3.*", "magento/module-webapi": "100.3.*", "magento/module-asynchronous-operations": "100.3.*" }, diff --git a/app/code/Magento/WebapiAsync/etc/di.xml b/app/code/Magento/WebapiAsync/etc/di.xml deleted file mode 100755 index 991afa556b35b..0000000000000 --- a/app/code/Magento/WebapiAsync/etc/di.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - Magento\WebapiAsync\Model\MessageQueue\MassPublisher - Magento\WebapiAsync\Model\MessageQueue\MassPublisher - - - - - - - - Magento\WebapiAsync\VirtualType\PublisherPool - - - - - - Magento\WebapiAsync\VirtualType\BulkManagement - - - - diff --git a/app/code/Magento/WebapiAsync/etc/queue_consumer.xml b/app/code/Magento/WebapiAsync/etc/queue_consumer.xml index a0c123847bc47..f8a1a18d754ef 100644 --- a/app/code/Magento/WebapiAsync/etc/queue_consumer.xml +++ b/app/code/Magento/WebapiAsync/etc/queue_consumer.xml @@ -8,5 +8,5 @@ + consumerInstance="Magento\AsynchronousOperations\Model\MassConsumer"/> \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/MassScheduleTest.php b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/Model/MassScheduleTest.php similarity index 98% rename from dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/MassScheduleTest.php rename to dev/tests/integration/testsuite/Magento/AsynchronousOperations/Model/MassScheduleTest.php index 93dfb429e26ee..0f3aa9c923a18 100644 --- a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/MessageQueue/MassScheduleTest.php +++ b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/Model/MassScheduleTest.php @@ -9,7 +9,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\WebapiAsync\Model\MessageQueue; +namespace Magento\AsynchronousOperations\Model; use Magento\Framework\Exception\BulkException; use Magento\Framework\Phrase; @@ -23,7 +23,6 @@ use Magento\Catalog\Model\ResourceModel\Product\Collection; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\ObjectManagerInterface; -use \Magento\WebapiAsync\Model\AsyncResponse\ItemStatus; class MassScheduleTest extends \PHPUnit\Framework\TestCase { From 21f07c9b3c2cffcad7eadb69ffea5b686b6004df Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" Date: Tue, 27 Mar 2018 16:09:22 +0300 Subject: [PATCH 252/668] fix undefined classes --- .../Model/BulkStatus.php | 4 ++-- .../Model/BulkStatus/Detailed.php | 21 ++----------------- .../Model/BulkStatus/Short.php | 21 ++----------------- 3 files changed, 6 insertions(+), 40 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php b/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php index 726d64ee87476..e46fac2fed6ae 100644 --- a/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php +++ b/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php @@ -233,7 +233,7 @@ public function getBulkDetailedStatus($bulkUuid) { $bulkSummary = $this->bulkDetailedFactory->create(); - /** @var \Magento\AsynchronousOperations\Api\Data\BulkStatus\DetailedInterface $bulk */ + /** @var \Magento\AsynchronousOperations\Api\Data\DetailedBulkStatusInterface $bulk */ $bulk = $this->entityManager->load($bulkSummary, $bulkUuid); if ($bulk->getBulkId() === null) { @@ -257,7 +257,7 @@ public function getBulkShortStatus($bulkUuid) { $bulkSummary = $this->bulkShortFactory->create(); - /** @var \Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterface $bulk */ + /** @var \Magento\AsynchronousOperations\Api\Data\BulkStatusInterface $bulk */ $bulk = $this->entityManager->load($bulkSummary, $bulkUuid); if ($bulk->getBulkId() === null) { throw new NoSuchEntityException( diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkStatus/Detailed.php b/app/code/Magento/AsynchronousOperations/Model/BulkStatus/Detailed.php index 175ac3a1d6d0c..8d5cf80e3f402 100644 --- a/app/code/Magento/AsynchronousOperations/Model/BulkStatus/Detailed.php +++ b/app/code/Magento/AsynchronousOperations/Model/BulkStatus/Detailed.php @@ -6,11 +6,10 @@ namespace Magento\AsynchronousOperations\Model\BulkStatus; -use Magento\AsynchronousOperations\Api\Data\BulkStatus\DetailedInterface; -use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface; +use Magento\AsynchronousOperations\Api\Data\DetailedBulkStatusInterface; use Magento\AsynchronousOperations\Model\BulkSummary; -class Detailed extends BulkSummary implements DetailedInterface +class Detailed extends BulkSummary implements DetailedBulkStatusInterface { /** * @inheritDoc @@ -27,20 +26,4 @@ public function setOperationsList($operationStatusList) { return $this->setData(self::OPERATIONS_LIST, $operationStatusList); } - - /** - * @inheritDoc - */ - public function getOperationsCounter() - { - return $this->getData(self::OPERATIONS_COUNTER); - } - - /** - * @inheritDoc - */ - public function setOperationsCounter(OperationDetailsInterface $operationDetails) - { - return $this->setData(self::OPERATIONS_COUNTER, $operationDetails); - } } diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkStatus/Short.php b/app/code/Magento/AsynchronousOperations/Model/BulkStatus/Short.php index abdeed34fb578..a11dc493aeeba 100644 --- a/app/code/Magento/AsynchronousOperations/Model/BulkStatus/Short.php +++ b/app/code/Magento/AsynchronousOperations/Model/BulkStatus/Short.php @@ -6,11 +6,10 @@ namespace Magento\AsynchronousOperations\Model\BulkStatus; -use Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterface; -use Magento\AsynchronousOperations\Api\Data\OperationDetailsInterface; +use Magento\AsynchronousOperations\Api\Data\BulkStatusInterface; use Magento\AsynchronousOperations\Model\BulkSummary; -class Short extends BulkSummary implements ShortInterface +class Short extends BulkSummary implements BulkStatusInterface { /** * @inheritDoc @@ -27,20 +26,4 @@ public function setOperationsList($operationStatusList) { return $this->setData(self::OPERATIONS_LIST, $operationStatusList); } - - /** - * @inheritDoc - */ - public function getOperationsCounter() - { - return $this->getData(self::OPERATIONS_COUNTER); - } - - /** - * @inheritDoc - */ - public function setOperationsCounter(OperationDetailsInterface $operationDetails) - { - return $this->setData(self::OPERATIONS_COUNTER, $operationDetails); - } } From 49c2e9875fd389676c7bbe31d4dea5f4988a0603 Mon Sep 17 00:00:00 2001 From: Andrii Meysar Date: Tue, 27 Mar 2018 16:28:56 +0300 Subject: [PATCH 253/668] MAGETWO-88180: Create Functional Test using contains condition operator. --- .../Test/Repository/CatalogProductSimple.xml | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml index 9270ec19c2a23..052fb0828b4d5 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml @@ -2156,5 +2156,59 @@ simple-product-%isolation% + + + + default + + Matching Product + sku_matching_product + This item has weight + 1 + + 25 + In Stock + + + 60 + + + taxable_goods + + + + default + + + Catalog, Search + matching-product + + + + + default + + Displayed Product + sku_displayed_product + This item has weight + 2 + + 35 + In Stock + + + 70 + + + taxable_goods + + + + default + + + Catalog, Search + displayed-product + From 5b8109315b1fdcc699789dcc0af216483fb19c2d Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Tue, 27 Mar 2018 08:41:10 -0500 Subject: [PATCH 254/668] MAGETWO-89082: Update composer dependencies --- composer.json | 2 +- composer.lock | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 064aa3ce1c078..13209780ffd5f 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ "colinmollenhour/php-redis-session-abstract": "~1.3.8", "composer/composer": "^1.6", "elasticsearch/elasticsearch": "~2.0|~5.1", - "magento/composer": "1.3.0.x-dev", + "magento/composer": "~1.3.0", "magento/magento-composer-installer": ">=0.1.11", "magento/zendframework1": "dev-master", "monolog/monolog": "^1.17", diff --git a/composer.lock b/composer.lock index b7e6448fb0054..be7645297af79 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "c2f827106b25e61999eec2b51090b369", + "content-hash": "a01a818f1c20967d8b6774be2a997966", "packages": [ { "name": "braintree/braintree_php", @@ -710,20 +710,20 @@ }, { "name": "magento/composer", - "version": "1.3.0.x-dev", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/magento/composer.git", - "reference": "21e4019f051513be041f5611fab717af63b5451e" + "reference": "38fdaa51967cd3dbed85cf695b6a70e3c2ff8a92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/composer/zipball/21e4019f051513be041f5611fab717af63b5451e", - "reference": "21e4019f051513be041f5611fab717af63b5451e", + "url": "https://api.github.com/repos/magento/composer/zipball/38fdaa51967cd3dbed85cf695b6a70e3c2ff8a92", + "reference": "38fdaa51967cd3dbed85cf695b6a70e3c2ff8a92", "shasum": "" }, "require": { - "composer/composer": "~1.6.0", + "composer/composer": "^1.6", "php": "~7.1.3|~7.2.0", "symfony/console": "~4.0.0" }, @@ -742,7 +742,7 @@ "AFL-3.0" ], "description": "Magento composer library helps to instantiate Composer application and run composer commands.", - "time": "2018-02-23T15:57:04+00:00" + "time": "2018-03-26T16:19:52+00:00" }, { "name": "magento/magento-composer-installer", @@ -6583,7 +6583,6 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "magento/composer": 20, "magento/zendframework1": 20, "phpmd/phpmd": 0 }, From b063c63eaa222da4d49ceeaa378d18f6e0cefd01 Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Tue, 27 Mar 2018 08:49:33 -0500 Subject: [PATCH 255/668] MAGETWO-89082: Update composer dependencies This reverts commit a97a662766b92cfcfb59bffbc1d6345415f2fb67. --- .../Magento/Framework/Amqp/composer.json | 26 +++++++++++++++++++ lib/internal/Magento/Framework/composer.json | 1 - 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 lib/internal/Magento/Framework/Amqp/composer.json diff --git a/lib/internal/Magento/Framework/Amqp/composer.json b/lib/internal/Magento/Framework/Amqp/composer.json new file mode 100644 index 0000000000000..f92b3ec22cb5b --- /dev/null +++ b/lib/internal/Magento/Framework/Amqp/composer.json @@ -0,0 +1,26 @@ +{ + "name": "magento/framework-amqp", + "description": "N/A", + "config": { + "sort-packages": true + }, + "type": "magento2-library", + "version": "100.1.0-dev", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "require": { + "magento/framework": "100.3.*", + "php": "~7.1.3||~7.2.0", + "php-amqplib/php-amqplib": "~2.7.0" + }, + "autoload": { + "psr-4": { + "Magento\\Framework\\Amqp\\": "" + }, + "files": [ + "registration.php" + ] + } +} diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json index 03a14f27f1441..c725413bf0533 100644 --- a/lib/internal/Magento/Framework/composer.json +++ b/lib/internal/Magento/Framework/composer.json @@ -27,7 +27,6 @@ "magento/zendframework1": "~1.13.0", "monolog/monolog": "^1.17", "oyejorge/less.php": "~1.7.0", - "php-amqplib/php-amqplib": "~2.7.0", "symfony/console": "~4.0.0", "symfony/process": "~4.0.0", "tedivm/jshrink": "~1.3.0", From 86fb290bd93a9f2e1d43a71fc9920c9e15353967 Mon Sep 17 00:00:00 2001 From: Eric Bohanon Date: Tue, 27 Mar 2018 09:27:36 -0500 Subject: [PATCH 256/668] MAGETWO-88936: Alter bundle collection to use selection id for link id. --- .../Model/Resolver/Links/Collection.php | 2 +- .../GraphQl/Bundle/BundleProductViewTest.php | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php index 0003ddedc5605..01c4ecf708e51 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php @@ -116,7 +116,7 @@ private function fetch() : array $formattedLink = [ 'price' => $link->getSelectionPriceValue(), 'position' => $link->getPosition(), - 'id' => $link->getId(), + 'id' => $link->getSelectionId(), 'qty' => (int)$link->getSelectionQty(), 'is_default' => (bool)$link->getIsDefault(), 'price_type' => $this->enumLookup->getEnumValueFromField( diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php index 2140f3fd9d751..9fbcd49bd85f2 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php @@ -6,9 +6,11 @@ namespace Magento\GraphQl\Bundle; +use Magento\Bundle\Api\Data\LinkInterface; use Magento\Bundle\Model\Product\OptionList; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\GraphQl\Query\EnumLookup; use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\GraphQlAbstract; @@ -16,6 +18,7 @@ class BundleProductViewTest extends GraphQlAbstract { const KEY_PRICE_TYPE_FIXED = 'FIXED'; + /** * @magentoApiDataFixture Magento/Bundle/_files/product_1.php */ @@ -77,7 +80,12 @@ public function testAllFielsBundleProducts() /** @var ProductRepositoryInterface $productRepository */ $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); + /** @var MetadataPool $metadataPool */ + $metadataPool = ObjectManager::getInstance()->get(MetadataPool::class); $bundleProduct = $productRepository->get($productSku, false, null, true); + $bundleProduct->setId( + $bundleProduct->getData($metadataPool->getMetadata(ProductInterface::class)->getLinkField()) + ); if ((bool)$bundleProduct->getShipmentType()) { $this->assertEquals('SEPARATELY', $response['products']['items'][0]['ship_bundle_items']); } else { @@ -128,6 +136,7 @@ private function assertBundleProductOptions($product, $actualResponse) $actualResponse['items'], "Precondition failed: 'bundle product items' must not be empty" ); + $metadataPool = ObjectManager::getInstance()->get(MetadataPool::class); /** @var OptionList $optionList */ $optionList = ObjectManager::getInstance()->get(\Magento\Bundle\Model\Product\OptionList::class); $options = $optionList->getItems($product); @@ -137,6 +146,10 @@ private function assertBundleProductOptions($product, $actualResponse) $childProductSku = $bundleProductLink->getSku(); $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); $childProduct = $productRepository->get($childProductSku); + /** @var MetadataPool $metadataPool */ + $childProduct->setId( + $childProduct->getData($metadataPool->getMetadata(ProductInterface::class)->getLinkField()) + ); $this->assertEquals(1, count($options)); $this->assertResponseFields( $actualResponse['items'][0], @@ -185,6 +198,11 @@ private function assertResponseFields($actualResponse, $assertionMap) ? $assertionData['expected_value'] : $assertionData; $responseField = isset($assertionData['response_field']) ? $assertionData['response_field'] : $key; + if ($responseField == 'id' && $expectedValue == null) { + var_dump($expectedValue); + var_dump($assertionData); + var_dump($assertionMap); + } $this->assertNotNull( $expectedValue, "Value of '{$responseField}' field must not be NULL" From 6f048ff2ee479897936d56f1bd5e6bf767efcf20 Mon Sep 17 00:00:00 2001 From: Joan He Date: Tue, 27 Mar 2018 09:51:59 -0500 Subject: [PATCH 257/668] MAGETWO-89567: Cannot set 'user' save handler by ini_set() --- .../Framework/Session/SessionManagerTest.php | 223 +++++++++++++----- 1 file changed, 162 insertions(+), 61 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php index fbada0f0dca36..c12399258fd27 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php @@ -10,7 +10,10 @@ namespace Magento\Framework\Session { + use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\State; + use Magento\Framework\Session\Config\ConfigInterface; + // @codingStandardsIgnoreEnd /** @@ -36,30 +39,72 @@ function headers_sent() return call_user_func_array('\headers_sent', func_get_args()); } + /** + * Mock ini_set global function + * + * @param string $varName + * @param string $newValue + * @return bool|string + */ + function ini_set($varName, $newValue) + { + global $mockPHPFunctions; + if ($mockPHPFunctions) { + SessionManagerTest::$isIniSetInvoked[$varName] = $newValue; + return true; + } + return call_user_func_array('\ini_set', func_get_args()); + } + + /** + * Mock session_set_save_handler global function + * + * @return bool + */ + function session_set_save_handler() + { + global $mockPHPFunctions; + if ($mockPHPFunctions) { + SessionManagerTest::$isSessionSetSaveHandlerInvoked = true; + return true; + } + return call_user_func_array('\session_set_save_handler', func_get_args()); + } + /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class SessionManagerTest extends \PHPUnit\Framework\TestCase { + /** + * @var string[] + */ + public static $isIniSetInvoked = []; + + /** + * @var bool + */ + public static $isSessionSetSaveHandlerInvoked; + /** * @var \Magento\Framework\Session\SessionManagerInterface */ - protected $_model; + private $model; /** * @var \Magento\Framework\Session\SidResolverInterface */ - protected $_sidResolver; + private $sidResolver; /** * @var string */ - protected $sessionName; + private $sessionName; /** - * @var \Magento\Framework\ObjectManagerInterface + * @var \Magento\TestFramework\ObjectManager */ - protected $objectManager; + private $objectManager; /** * @var \Magento\Framework\App\RequestInterface @@ -79,6 +124,21 @@ protected function setUp() ini_set('session.name', $this->sessionName); $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $deploymentConfigMock = $this->createMock(DeploymentConfig::class); + $deploymentConfigMock->method('get') + ->willReturnCallback(function ($configPath) { + switch ($configPath) { + case Config::PARAM_SESSION_SAVE_METHOD: + return 'db'; + case Config::PARAM_SESSION_CACHE_LIMITER: + return 'private_no_expire'; + case Config::PARAM_SESSION_SAVE_PATH: + return 'explicit_save_path'; + default: + return null; + } + }); + $this->objectManager->addSharedInstance($deploymentConfigMock, DeploymentConfig::class); /** @var \Magento\Framework\Session\SidResolverInterface $sidResolver */ $this->appState = $this->getMockBuilder(State::class) @@ -87,7 +147,7 @@ protected function setUp() ->getMock(); /** @var \Magento\Framework\Session\SidResolver $sidResolver */ - $this->_sidResolver = $this->objectManager->create( + $this->sidResolver = $this->objectManager->create( \Magento\Framework\Session\SidResolver::class, [ 'appState' => $this->appState, @@ -95,37 +155,32 @@ protected function setUp() ); $this->request = $this->objectManager->get(\Magento\Framework\App\RequestInterface::class); - - /** @var \Magento\Framework\Session\SessionManager _model */ - $this->_model = $this->objectManager->create( - \Magento\Framework\Session\SessionManager::class, - [ - $this->objectManager->get(\Magento\Framework\App\Request\Http::class), - $this->_sidResolver, - $this->objectManager->get(\Magento\Framework\Session\Config\ConfigInterface::class), - $this->objectManager->get(\Magento\Framework\Session\SaveHandlerInterface::class), - $this->objectManager->get(\Magento\Framework\Session\ValidatorInterface::class), - $this->objectManager->get(\Magento\Framework\Session\StorageInterface::class) - ] - ); } protected function tearDown() { global $mockPHPFunctions; $mockPHPFunctions = false; - $this->_model->destroy(); + self::$isIniSetInvoked = []; + self::$isSessionSetSaveHandlerInvoked = false; + if ($this->model !== null) { + $this->model->destroy(); + $this->model = null; + } + $this->objectManager->removeSharedInstance(DeploymentConfig::class); } public function testSessionNameFromIni() { - $this->_model->start(); - $this->assertSame($this->sessionName, $this->_model->getName()); - $this->_model->destroy(); + $this->initializeModel(); + $this->model->start(); + $this->assertSame($this->sessionName, $this->model->getName()); + $this->model->destroy(); } public function testSessionUseOnlyCookies() { + $this->initializeModel(); $expectedValue = '1'; $sessionUseOnlyCookies = ini_get('session.use_only_cookies'); $this->assertSame($expectedValue, $sessionUseOnlyCookies); @@ -133,51 +188,57 @@ public function testSessionUseOnlyCookies() public function testGetData() { - $this->_model->setData(['test_key' => 'test_value']); - $this->assertEquals('test_value', $this->_model->getData('test_key', true)); - $this->assertNull($this->_model->getData('test_key')); + $this->initializeModel(); + $this->model->setData(['test_key' => 'test_value']); + $this->assertEquals('test_value', $this->model->getData('test_key', true)); + $this->assertNull($this->model->getData('test_key')); } public function testGetSessionId() { - $this->assertEquals(session_id(), $this->_model->getSessionId()); + $this->initializeModel(); + $this->assertEquals(session_id(), $this->model->getSessionId()); } public function testGetName() { - $this->assertEquals(session_name(), $this->_model->getName()); + $this->initializeModel(); + $this->assertEquals(session_name(), $this->model->getName()); } public function testSetName() { - $this->_model->destroy(); - $this->_model->setName('test'); - $this->_model->start(); - $this->assertEquals('test', $this->_model->getName()); + $this->initializeModel(); + $this->model->destroy(); + $this->model->setName('test'); + $this->model->start(); + $this->assertEquals('test', $this->model->getName()); } public function testDestroy() { + $this->initializeModel(); $data = ['key' => 'value']; - $this->_model->setData($data); + $this->model->setData($data); - $this->assertEquals($data, $this->_model->getData()); - $this->_model->destroy(); + $this->assertEquals($data, $this->model->getData()); + $this->model->destroy(); - $this->assertEquals([], $this->_model->getData()); + $this->assertEquals([], $this->model->getData()); } public function testSetSessionId() { - $sessionId = $this->_model->getSessionId(); + $this->initializeModel(); + $sessionId = $this->model->getSessionId(); $this->appState->expects($this->atLeastOnce()) ->method('getAreaCode') ->willReturn(\Magento\Framework\App\Area::AREA_FRONTEND); - $this->_model->setSessionId($this->_sidResolver->getSid($this->_model)); - $this->assertEquals($sessionId, $this->_model->getSessionId()); + $this->model->setSessionId($this->sidResolver->getSid($this->model)); + $this->assertEquals($sessionId, $this->model->getSessionId()); - $this->_model->setSessionId('test'); - $this->assertEquals('test', $this->_model->getSessionId()); + $this->model->setSessionId('test'); + $this->assertEquals('test', $this->model->getSessionId()); } /** @@ -185,40 +246,43 @@ public function testSetSessionId() */ public function testSetSessionIdFromParam() { + $this->initializeModel(); $this->appState->expects($this->atLeastOnce()) ->method('getAreaCode') ->willReturn(\Magento\Framework\App\Area::AREA_FRONTEND); - $this->assertNotEquals('test_id', $this->_model->getSessionId()); - $this->request->getQuery()->set($this->_sidResolver->getSessionIdQueryParam($this->_model), 'test-id'); - $this->_model->setSessionId($this->_sidResolver->getSid($this->_model)); - $this->assertEquals('test-id', $this->_model->getSessionId()); + $this->assertNotEquals('test_id', $this->model->getSessionId()); + $this->request->getQuery()->set($this->sidResolver->getSessionIdQueryParam($this->model), 'test-id'); + $this->model->setSessionId($this->sidResolver->getSid($this->model)); + $this->assertEquals('test-id', $this->model->getSessionId()); /* Use not valid identifier */ - $this->request->getQuery()->set($this->_sidResolver->getSessionIdQueryParam($this->_model), 'test_id'); - $this->_model->setSessionId($this->_sidResolver->getSid($this->_model)); - $this->assertEquals('test-id', $this->_model->getSessionId()); + $this->request->getQuery()->set($this->sidResolver->getSessionIdQueryParam($this->model), 'test_id'); + $this->model->setSessionId($this->sidResolver->getSid($this->model)); + $this->assertEquals('test-id', $this->model->getSessionId()); } public function testGetSessionIdForHost() { + $this->initializeModel(); $_SERVER['HTTP_HOST'] = 'localhost'; - $this->_model->start(); - $this->assertEmpty($this->_model->getSessionIdForHost('localhost')); - $this->assertNotEmpty($this->_model->getSessionIdForHost('test')); - $this->_model->destroy(); + $this->model->start(); + $this->assertEmpty($this->model->getSessionIdForHost('localhost')); + $this->assertNotEmpty($this->model->getSessionIdForHost('test')); + $this->model->destroy(); } public function testIsValidForHost() { + $this->initializeModel(); $_SERVER['HTTP_HOST'] = 'localhost'; - $this->_model->start(); + $this->model->start(); - $reflection = new \ReflectionMethod($this->_model, '_addHost'); + $reflection = new \ReflectionMethod($this->model, '_addHost'); $reflection->setAccessible(true); - $reflection->invoke($this->_model); + $reflection->invoke($this->model); - $this->assertFalse($this->_model->isValidForHost('test.com')); - $this->assertTrue($this->_model->isValidForHost('localhost')); - $this->_model->destroy(); + $this->assertFalse($this->model->isValidForHost('test.com')); + $this->assertTrue($this->model->isValidForHost('localhost')); + $this->model->destroy(); } /** @@ -236,9 +300,9 @@ public function testStartAreaNotSet() * * @var \Magento\Framework\Session\SessionManager _model */ - $this->_model = new \Magento\Framework\Session\SessionManager( + $this->model = new \Magento\Framework\Session\SessionManager( $this->objectManager->get(\Magento\Framework\App\Request\Http::class), - $this->_sidResolver, + $this->sidResolver, $this->objectManager->get(\Magento\Framework\Session\Config\ConfigInterface::class), $this->objectManager->get(\Magento\Framework\Session\SaveHandlerInterface::class), $this->objectManager->get(\Magento\Framework\Session\ValidatorInterface::class), @@ -250,7 +314,44 @@ public function testStartAreaNotSet() global $mockPHPFunctions; $mockPHPFunctions = true; - $this->_model->start(); + $this->model->start(); + } + + public function testConstructor() + { + global $mockPHPFunctions; + $mockPHPFunctions = true; + $this->model = $this->objectManager->create( + \Magento\Framework\Session\SessionManager::class, + [ + 'sidResolver' => $this->sidResolver + ] + ); + $sessionConfig = $this->objectManager->get(ConfigInterface::class); + $this->assertEquals('db', $sessionConfig->getOption('session.save_handler')); + $this->assertEquals('private_no_expire', $sessionConfig->getOption('session.cache_limiter')); + $this->assertEquals('explicit_save_path', $sessionConfig->getOption('session.save_path')); + $this->assertArrayHasKey('session.use_only_cookies', self::$isIniSetInvoked); + $this->assertEquals('1', self::$isIniSetInvoked['session.use_only_cookies']); + foreach ($sessionConfig->getOptions() as $option => $value) { + if ($option=='session.save_handler') { + $this->assertArrayNotHasKey('session.save_handler', self::$isIniSetInvoked); + } else { + $this->assertArrayHasKey($option, self::$isIniSetInvoked); + $this->assertEquals($value, self::$isIniSetInvoked[$option]); + } + } + $this->assertTrue(self::$isSessionSetSaveHandlerInvoked); + } + + private function initializeModel(): void + { + $this->model = $this->objectManager->create( + \Magento\Framework\Session\SessionManager::class, + [ + 'sidResolver' => $this->sidResolver + ] + ); } } } From 7cfbf6741f6326b4614a92207ee50f7e0bb1a443 Mon Sep 17 00:00:00 2001 From: Bartek Igielski Date: Tue, 27 Mar 2018 17:35:17 +0200 Subject: [PATCH 258/668] Unused variable removed --- lib/web/css/source/lib/variables/_typography.less | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/web/css/source/lib/variables/_typography.less b/lib/web/css/source/lib/variables/_typography.less index aae7997478545..bf88990fe05c8 100644 --- a/lib/web/css/source/lib/variables/_typography.less +++ b/lib/web/css/source/lib/variables/_typography.less @@ -12,7 +12,6 @@ // --------------------------------------------- // Path -@font-path: "../../fonts/"; @icons__font-path: "@{baseDir}fonts/Blank-Theme-Icons/Blank-Theme-Icons"; // Names From 7fc27af4dd3434ab9921e77433557b4d121d378e Mon Sep 17 00:00:00 2001 From: olysenko Date: Tue, 27 Mar 2018 18:40:25 +0300 Subject: [PATCH 259/668] MAGETWO-89382: Automate MAGETWO-46344 MFTF --- .../FunctionalTest/Catalog/Data/CategoryData.xml | 7 ++++++- .../Catalog/Test/DeleteCategoriesTest.xml | 2 +- .../Catalog/Test/EndToEndB2CGuestUserTest.xml | 12 ++++-------- .../Catalog/Test/EndToEndB2CLoggedInUserTest.xml | 12 ++++-------- .../Checkout/Test/EndToEndB2CGuestUserTest.xml | 6 ++---- .../Checkout/Test/EndToEndB2CLoggedInUserTest.xml | 6 ++---- .../Test/EndToEndB2CGuestUserTest.xml | 3 +-- .../Test/EndToEndB2CLoggedInUserTest.xml | 3 +-- 8 files changed, 21 insertions(+), 30 deletions(-) diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/CategoryData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/CategoryData.xml index d76c1286f2636..a1147888a74c5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/CategoryData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/CategoryData.xml @@ -22,7 +22,6 @@ simplesubcategory true true - NewRootCategory @@ -31,4 +30,10 @@ true 1 + + subCategory + subCategory + true + + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml index 6c8d1885ac8dc..166ab1d839a48 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml @@ -23,7 +23,7 @@ - + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/EndToEndB2CGuestUserTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/EndToEndB2CGuestUserTest.xml index 981737770f24b..54782ca8ca530 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/EndToEndB2CGuestUserTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/EndToEndB2CGuestUserTest.xml @@ -68,8 +68,7 @@ - - + @@ -120,8 +119,7 @@ - - + @@ -147,8 +145,7 @@ - - + @@ -196,8 +193,7 @@ - - + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/EndToEndB2CLoggedInUserTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/EndToEndB2CLoggedInUserTest.xml index a903290940ced..9bd00ea3aef32 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/EndToEndB2CLoggedInUserTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/EndToEndB2CLoggedInUserTest.xml @@ -57,8 +57,7 @@ - - + @@ -109,8 +108,7 @@ - - + @@ -136,8 +134,7 @@ - - + @@ -183,8 +180,7 @@ - - + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Test/EndToEndB2CGuestUserTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Test/EndToEndB2CGuestUserTest.xml index d512aebb2c243..8bee75f53c6b2 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Test/EndToEndB2CGuestUserTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Test/EndToEndB2CGuestUserTest.xml @@ -17,8 +17,7 @@ - - + @@ -46,8 +45,7 @@ - - + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Test/EndToEndB2CLoggedInUserTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Test/EndToEndB2CLoggedInUserTest.xml index 1cd30954d7f51..74f815181cf9d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Test/EndToEndB2CLoggedInUserTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Test/EndToEndB2CLoggedInUserTest.xml @@ -17,8 +17,7 @@ - - + @@ -46,8 +45,7 @@ - - + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/EndToEndB2CGuestUserTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/EndToEndB2CGuestUserTest.xml index d3791f4d52657..d98ab9d50890e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/EndToEndB2CGuestUserTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/EndToEndB2CGuestUserTest.xml @@ -112,8 +112,7 @@ - - + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/EndToEndB2CLoggedInUserTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/EndToEndB2CLoggedInUserTest.xml index b1b73d40da144..a75aa8c27f099 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/EndToEndB2CLoggedInUserTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/EndToEndB2CLoggedInUserTest.xml @@ -112,8 +112,7 @@ - - + From 11f37435e3d2ffa2d419a757bdc48e56915d1bfb Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 27 Mar 2018 11:19:42 -0500 Subject: [PATCH 260/668] MAGETWO-89292: Implement SDL from prototype - moving sql to separate module --- app/code/Magento/CatalogGraphQl/etc/di.xml | 2 +- app/code/Magento/GraphQl/etc/di.xml | 18 +++++++++--------- .../Common/Reader.php | 2 +- .../GraphQlReader.php | 17 +++++++++++------ .../GraphQlReader/MetaReader/DocReader.php | 2 +- .../MetaReader/FieldMetaReader.php | 4 ++-- .../MetaReader/ImplementsReader.php | 2 +- .../MetaReader/TypeMetaWrapperReader.php | 4 +++- .../GraphQlReader/Reader/EnumType.php | 9 ++++++--- .../GraphQlReader/Reader/InputObjectType.php | 11 +++++++---- .../GraphQlReader/Reader/InterfaceType.php | 11 +++++++---- .../GraphQlReader/Reader/ObjectType.php | 13 ++++++++----- .../GraphQlReader/TypeMetaReaderInterface.php | 7 +++++-- .../GraphQlReader/TypeReaderComposite.php} | 7 +++++-- 14 files changed, 67 insertions(+), 42 deletions(-) rename lib/internal/Magento/Framework/{GraphQl/Config => GraphqlModularSchema}/Common/Reader.php (93%) rename lib/internal/Magento/Framework/{GraphQl/Config => GraphqlModularSchema}/GraphQlReader.php (95%) rename lib/internal/Magento/Framework/{GraphQl/Config => GraphqlModularSchema}/GraphQlReader/MetaReader/DocReader.php (92%) rename lib/internal/Magento/Framework/{GraphQl/Config => GraphqlModularSchema}/GraphQlReader/MetaReader/FieldMetaReader.php (95%) rename lib/internal/Magento/Framework/{GraphQl/Config => GraphqlModularSchema}/GraphQlReader/MetaReader/ImplementsReader.php (94%) rename lib/internal/Magento/Framework/{GraphQl/Config => GraphqlModularSchema}/GraphQlReader/MetaReader/TypeMetaWrapperReader.php (96%) rename lib/internal/Magento/Framework/{GraphQl/Config => GraphqlModularSchema}/GraphQlReader/Reader/EnumType.php (83%) rename lib/internal/Magento/Framework/{GraphQl/Config => GraphqlModularSchema}/GraphQlReader/Reader/InputObjectType.php (85%) rename lib/internal/Magento/Framework/{GraphQl/Config => GraphqlModularSchema}/GraphQlReader/Reader/InterfaceType.php (86%) rename lib/internal/Magento/Framework/{GraphQl/Config => GraphqlModularSchema}/GraphQlReader/Reader/ObjectType.php (84%) rename lib/internal/Magento/Framework/{GraphQl/Config => GraphqlModularSchema}/GraphQlReader/TypeMetaReaderInterface.php (54%) rename lib/internal/Magento/Framework/{GraphQl/Config/GraphQlReader/TypeReader.php => GraphqlModularSchema/GraphQlReader/TypeReaderComposite.php} (75%) diff --git a/app/code/Magento/CatalogGraphQl/etc/di.xml b/app/code/Magento/CatalogGraphQl/etc/di.xml index b7338139e5b9f..dd0c7de52f00f 100644 --- a/app/code/Magento/CatalogGraphQl/etc/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/di.xml @@ -20,7 +20,7 @@ - + Magento\CatalogGraphQl\Model\Config\AttributeReader diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 215148f1420bc..dc178e1a411d3 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -34,8 +34,8 @@ - Magento\Framework\GraphQl\Config\Reader - Magento_Framework_GraphQl_Config_Data + Magento\Framework\GraphQlModularSchema\Reader + Magento_Framework_GraphQlModularSchema_Config_Data @@ -43,10 +43,10 @@ urn:magento:module:Magento_GraphQl:etc/graphql.xsd - + - Magento\Framework\GraphQl\Config\GraphQlReader + Magento\Framework\GraphQlModularSchema\GraphQlReader @@ -82,13 +82,13 @@ - + - Magento\Framework\GraphQl\Config\GraphQlReader\Reader\EnumType - Magento\Framework\GraphQl\Config\GraphQlReader\Reader\ObjectType - Magento\Framework\GraphQl\Config\GraphQlReader\Reader\InputObjectType - Magento\Framework\GraphQl\Config\GraphQlReader\Reader\InterfaceType + Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader\EnumType + Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader\ObjectType + Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader\InputObjectType + Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader\InterfaceType diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php b/lib/internal/Magento/Framework/GraphqlModularSchema/Common/Reader.php similarity index 93% rename from lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php rename to lib/internal/Magento/Framework/GraphqlModularSchema/Common/Reader.php index 951a6cc4eb945..3e6fd404c119d 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Common/Reader.php +++ b/lib/internal/Magento/Framework/GraphqlModularSchema/Common/Reader.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\Framework\GraphQl\Config\Common; +namespace Magento\Framework\GraphQlModularSchema\Common; use Magento\Framework\Config\ReaderInterface; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader.php similarity index 95% rename from lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php rename to lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader.php index d8ef31d0a9a45..57bce75774172 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader.php @@ -5,16 +5,21 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQl\Config; +namespace Magento\Framework\GraphQlModularSchema; use Magento\Framework\Config\FileResolverInterface; -use Magento\Framework\GraphQl\Config\GraphQlReader\TypeReader; +use Magento\Framework\GraphqlModularSchema\GraphQlReader\TypeReaderComposite; use Magento\Framework\Config\ReaderInterface; +/** + * Reads *.graphqls files from modules and combines the results as array to be used with a library to configure objects + */ class GraphQlReader implements ReaderInterface { const GRAPHQL_PLACEHOLDER_FIELD_NAME = 'placeholder_graphql_field'; + const GRAPHQL_SCHEMA_FILE = 'schema.graphqls'; + /** * File locator * @@ -23,7 +28,7 @@ class GraphQlReader implements ReaderInterface private $fileResolver; /** - * @var TypeReader + * @var TypeReaderComposite */ private $typeReader; @@ -39,14 +44,14 @@ class GraphQlReader implements ReaderInterface /** * @param FileResolverInterface $fileResolver - * @param TypeReader $typeReader + * @param TypeReaderComposite $typeReader * @param string $fileName * @param string $defaultScope */ public function __construct( FileResolverInterface $fileResolver, - TypeReader $typeReader, - $fileName = 'schema.graphqls', + TypeReaderComposite $typeReader, + $fileName = self::GRAPHQL_SCHEMA_FILE, $defaultScope = 'global' ) { $this->fileResolver = $fileResolver; diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/DocReader.php b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/DocReader.php similarity index 92% rename from lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/DocReader.php rename to lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/DocReader.php index 0f647fd111770..bfe4d2e2b381b 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/DocReader.php +++ b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/DocReader.php @@ -5,7 +5,7 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader; +namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader; /** * Reads documentation from the annotation @doc of an AST node diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/FieldMetaReader.php similarity index 95% rename from lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php rename to lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/FieldMetaReader.php index f4ef3dd51c0f9..67066bc3e8a99 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/FieldMetaReader.php +++ b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/FieldMetaReader.php @@ -5,9 +5,9 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader; +namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader; -use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\TypeMetaWrapperReader; +use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\TypeMetaWrapperReader; /** * Reads fields and possible arguments from a meta field diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/ImplementsReader.php b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/ImplementsReader.php similarity index 94% rename from lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/ImplementsReader.php rename to lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/ImplementsReader.php index b7a149c2dd78c..23f5ebda03cdc 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/ImplementsReader.php +++ b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/ImplementsReader.php @@ -5,7 +5,7 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader; +namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader; /** * Reads interfaces implementations from the annotation @implements of an AST node diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaWrapperReader.php b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/TypeMetaWrapperReader.php similarity index 96% rename from lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaWrapperReader.php rename to lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/TypeMetaWrapperReader.php index fb25d4b90aca7..3a899c3e24695 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/MetaReader/TypeMetaWrapperReader.php +++ b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/TypeMetaWrapperReader.php @@ -5,7 +5,7 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader; +namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader; /** * Common cases for types that need extra formatting like wrapping or additional properties added to their definition @@ -13,7 +13,9 @@ class TypeMetaWrapperReader { const ARGUMENT_PARAMETER = 'Argument'; + const OUTPUT_FIELD_PARAMETER = 'OutputField'; + const INPUT_FIELD_PARAMETER = 'InputField'; /** diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/EnumType.php similarity index 83% rename from lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php rename to lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/EnumType.php index c0a9a4d09c5d4..4ac2fb341b8c0 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/EnumType.php +++ b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/EnumType.php @@ -5,11 +5,14 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQl\Config\GraphQlReader\Reader; +namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader; -use Magento\Framework\GraphQl\Config\GraphQlReader\TypeMetaReaderInterface; -use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\DocReader; +use Magento\Framework\GraphQlModularSchema\GraphQlReader\TypeMetaReaderInterface; +use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\DocReader; +/** + * Composite configuration reader to handle the enum type meta + */ class EnumType implements TypeMetaReaderInterface { /** diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/InputObjectType.php similarity index 85% rename from lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php rename to lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/InputObjectType.php index 9ba5d9c4fa612..df5349822d70f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/InputObjectType.php @@ -5,12 +5,15 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQl\Config\GraphQlReader\Reader; +namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader; -use Magento\Framework\GraphQl\Config\GraphQlReader\TypeMetaReaderInterface; -use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\TypeMetaWrapperReader; -use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\DocReader; +use Magento\Framework\GraphQlModularSchema\GraphQlReader\TypeMetaReaderInterface; +use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\TypeMetaWrapperReader; +use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\DocReader; +/** + * Composite configuration reader to handle the input object type meta + */ class InputObjectType implements TypeMetaReaderInterface { /** diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/InterfaceType.php similarity index 86% rename from lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php rename to lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/InterfaceType.php index 58349e956bf1e..340623920d431 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/InterfaceType.php +++ b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/InterfaceType.php @@ -5,12 +5,15 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQl\Config\GraphQlReader\Reader; +namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader; -use Magento\Framework\GraphQl\Config\GraphQlReader\TypeMetaReaderInterface; -use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\FieldMetaReader; -use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\DocReader; +use Magento\Framework\GraphQlModularSchema\GraphQlReader\TypeMetaReaderInterface; +use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\FieldMetaReader; +use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\DocReader; +/** + * Composite configuration reader to handle the interface object type meta + */ class InterfaceType implements TypeMetaReaderInterface { /** diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/ObjectType.php similarity index 84% rename from lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php rename to lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/ObjectType.php index dab207e51770f..7adeb89afb15f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/Reader/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/ObjectType.php @@ -5,13 +5,16 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQl\Config\GraphQlReader\Reader; +namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader; -use Magento\Framework\GraphQl\Config\GraphQlReader\TypeMetaReaderInterface; -use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\FieldMetaReader; -use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\DocReader; -use Magento\Framework\GraphQl\Config\GraphQlReader\MetaReader\ImplementsReader; +use Magento\Framework\GraphQlModularSchema\GraphQlReader\TypeMetaReaderInterface; +use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\FieldMetaReader; +use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\DocReader; +use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\ImplementsReader; +/** + * Composite configuration reader to handle the object type meta + */ class ObjectType implements TypeMetaReaderInterface { /** diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/TypeMetaReaderInterface.php b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/TypeMetaReaderInterface.php similarity index 54% rename from lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/TypeMetaReaderInterface.php rename to lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/TypeMetaReaderInterface.php index d63901e27ce02..9e9e68e9c077f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/TypeMetaReaderInterface.php +++ b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/TypeMetaReaderInterface.php @@ -5,12 +5,15 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQl\Config\GraphQlReader; +namespace Magento\Framework\GraphQlModularSchema\GraphQlReader; +/** + * Reads and returns metadata as array for a specific type if it finds an adequate implementation for that type + */ interface TypeMetaReaderInterface { /** - * Read schema data from type metadata + * Read schema data from type metadata if proper type is provided for a specific implementation * * @param \GraphQL\Type\Definition\Type $typeMeta * @return array diff --git a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/TypeReader.php b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/TypeReaderComposite.php similarity index 75% rename from lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/TypeReader.php rename to lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/TypeReaderComposite.php index 648ad9634dd88..d7b500056c8cc 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/GraphQlReader/TypeReader.php +++ b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/TypeReaderComposite.php @@ -5,9 +5,12 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQl\Config\GraphQlReader; +namespace Magento\Framework\GraphQlModularSchema\GraphQlReader; -class TypeReader implements TypeMetaReaderInterface +/** + * Composite configured class used to determine which reader should be used for a specific type + */ +class TypeReaderComposite implements TypeMetaReaderInterface { /** @var TypeMetaReaderInterface[] */ private $typeReaders = []; From b3c0da6062fb6a39866caf76a29e81cd15a51780 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 27 Mar 2018 12:55:39 -0500 Subject: [PATCH 261/668] MAGETWO-89292: Implement SDL from prototype - adding interface --- app/code/Magento/GraphQl/etc/di.xml | 1 + .../Magento/Framework/GraphqlModularSchema/GraphQlReader.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index dc178e1a411d3..1fd95532ead14 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -11,6 +11,7 @@ + diff --git a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader.php b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader.php index 57bce75774172..99134b37fc98c 100644 --- a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader.php @@ -8,7 +8,7 @@ namespace Magento\Framework\GraphQlModularSchema; use Magento\Framework\Config\FileResolverInterface; -use Magento\Framework\GraphqlModularSchema\GraphQlReader\TypeReaderComposite; +use Magento\Framework\GraphqlModularSchema\GraphQlReader\TypeMetaReaderInterface as TypeReaderComposite; use Magento\Framework\Config\ReaderInterface; /** From 69f12e7dfb41645e59e264597a5c0c41940e1399 Mon Sep 17 00:00:00 2001 From: Eric Bohanon Date: Tue, 27 Mar 2018 12:58:00 -0500 Subject: [PATCH 262/668] MAGETWO-88936: Fix configurable products functional test --- .../ConfigurableProductViewTest.php | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php index e18eb5a261542..02e24d5da8caa 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/ConfigurableProductViewTest.php @@ -8,6 +8,8 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Pricing\Price\FinalPrice; +use Magento\Catalog\Pricing\Price\RegularPrice; use Magento\Framework\EntityManager\MetadataPool; use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\GraphQlAbstract; @@ -207,11 +209,6 @@ public function testQueryConfigurableProductLinks() $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); $product = $productRepository->get($productSku, false, null, true); - /** @var MetadataPool $metadataPool */ - $metadataPool = ObjectManager::getInstance()->get(MetadataPool::class); - $product->setId( - $product->getData($metadataPool->getMetadata(ProductInterface::class)->getLinkField()) - ); $this->assertArrayHasKey('products', $response); $this->assertArrayHasKey('items', $response['products']); @@ -228,11 +225,28 @@ public function testQueryConfigurableProductLinks() */ private function assertBaseFields($product, $actualResponse) { + /** @var \Magento\Framework\Pricing\PriceInfo\Factory $priceInfoFactory */ + $priceInfoFactory = ObjectManager::getInstance()->get(\Magento\Framework\Pricing\PriceInfo\Factory::class); + $priceInfo = $priceInfoFactory->create($product); + /** @var \Magento\Catalog\Pricing\Price\FinalPriceInterface $finalPrice */ + $finalPrice = $priceInfo->getPrice(FinalPrice::PRICE_CODE); + $minimalPriceAmount = $finalPrice->getMinimalPrice(); + $maximalPriceAmount = $finalPrice->getMaximalPrice(); + $regularPriceAmount = $priceInfo->getPrice(RegularPrice::PRICE_CODE)->getAmount(); + /** @var MetadataPool $metadataPool */ + $metadataPool = ObjectManager::getInstance()->get(MetadataPool::class); // ['product_object_field_name', 'expected_value'] $assertionMap = [ ['response_field' => 'attribute_set_id', 'expected_value' => $product->getAttributeSetId()], ['response_field' => 'created_at', 'expected_value' => $product->getCreatedAt()], - ['response_field' => 'id', 'expected_value' => $product->getId()], + [ + 'response_field' => 'id', + 'expected_value' => $product->getData( + $metadataPool->getMetadata( + ProductInterface::class + )->getLinkField() + ) + ], ['response_field' => 'name', 'expected_value' => $product->getName()], ['response_field' => 'sku', 'expected_value' => $product->getSku()], ['response_field' => 'type_id', 'expected_value' => $product->getTypeId()], @@ -243,21 +257,21 @@ private function assertBaseFields($product, $actualResponse) 'expected_value' => [ 'minimalPrice' => [ 'amount' => [ - 'value' => $product->getFinalPrice(), + 'value' => $minimalPriceAmount->getValue(), 'currency' => 'USD' ], 'adjustments' => [] ], 'regularPrice' => [ 'amount' => [ - 'value' => $product->getFinalPrice(), + 'value' => $maximalPriceAmount->getValue(), 'currency' => 'USD' ], 'adjustments' => [] ], 'maximalPrice' => [ 'amount' => [ - 'value' => $product->getFinalPrice(), + 'value' => $regularPriceAmount->getValue(), 'currency' => 'USD' ], 'adjustments' => [] @@ -288,7 +302,7 @@ private function assertConfigurableVariants($actualResponse) isset($variantArray['product']['id']), 'variant product elements don\'t contain id key' ); - $indexValue = $variantArray['product']['id']; + $indexValue = $variantArray['product']['sku']; unset($variantArray['product']['id']); $this->assertTrue( isset($variantArray['product']['category_ids']), @@ -300,7 +314,8 @@ private function assertConfigurableVariants($actualResponse) ); $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); /** @var \Magento\Catalog\Model\Product $childProduct */ - $childProduct = $productRepository->getById($indexValue); + $childProduct = $productRepository->get($indexValue); + var_dump($childProduct->getSku()); /** @var \Magento\Catalog\Api\Data\ProductLinkInterface[] */ $links = $childProduct->getExtensionAttributes()->getCategoryLinks(); From b9c5081e7d7a89a0914ace3dc27912006b66ea19 Mon Sep 17 00:00:00 2001 From: Eric Bohanon Date: Tue, 27 Mar 2018 13:34:40 -0500 Subject: [PATCH 263/668] MAGETWO-88936: Limit query depth --- lib/internal/Magento/Framework/GraphQl/QueryProcessor.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php index 9c8ae54195fa3..2d82d8961c842 100644 --- a/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php @@ -7,6 +7,8 @@ namespace Magento\Framework\GraphQl; +use GraphQL\Validator\DocumentValidator; +use GraphQL\Validator\Rules\QueryDepth; use Magento\Framework\GraphQl\Type\Schema; /** @@ -46,6 +48,8 @@ public function process( $variableValues = null, $operationName = null ) { + $rule = new QueryDepth(10); + DocumentValidator::addRule($rule); return \GraphQL\GraphQL::executeQuery( $schema, $source, From 3277183b0aa495de241f6220fd7d26ff388db801 Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Tue, 27 Mar 2018 13:52:06 -0500 Subject: [PATCH 264/668] MAGETWO-89366: Create integration or api tests - updated tests to accommodate changed class names --- .../GraphQl/Catalog/ProductSearchTest.php | 81 ++++++++++++++++++- .../GraphQl/Config/GraphQlReaderTest.php | 19 ++--- .../{schemaA.graphql => schemaA.graphqls} | 0 .../{schemaB.graphql => schemaB.graphqls} | 0 4 files changed, 88 insertions(+), 12 deletions(-) rename dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/{schemaA.graphql => schemaA.graphqls} (100%) rename dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/{schemaB.graphql => schemaB.graphqls} (100%) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php index b666332d9a57d..a999d7c0f669b 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php @@ -6,6 +6,7 @@ namespace Magento\GraphQl\Catalog; +use Magento\Catalog\Api\CategoryLinkManagementInterface; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\TestFramework\ObjectManager; @@ -490,7 +491,7 @@ public function testFilteringForProductInMultipleCategories() ]; $this->assertResponseFields($response['products']['items'][0], $assertionMap); } - + /** * Sorting by price in the DESC order from the filtered items with default pageSize * @@ -565,6 +566,52 @@ public function testQuerySortByPriceDESCWithDefaultPageSize() $this->assertEquals(1, $response['products']['page_info']['current_page']); } + /** + * @magentoApiDataFixture Magento/Catalog/_files/multiple_mixed_products_2.php + */ + public function testProductQueryUsingFromAndToFilterInput(){ + $query + = <<graphQlQuery($query); + $this->assertEquals(2, $response['products']['total_count']); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); + $product1 = $productRepository->get('simple1'); + $product2 = $productRepository->get('simple2'); + $filteredProducts = [$product1, $product2]; + $this->assertProductItemsWithMaximalAndMinimalPriceCheck($filteredProducts, $response); + } + /** * No items are returned if the conditions are not met * @@ -751,6 +798,38 @@ private function assertProductItems(array $filteredProducts, array $actualRespon } } + private function assertProductItemsWithMaximalAndMinimalPriceCheck(array $filteredProducts, array $actualResponse) + { + $productItemsInResponse = array_map(null, $actualResponse['products']['items'], $filteredProducts); + + foreach ($productItemsInResponse as $itemIndex => $itemArray) { + $this->assertNotEmpty($itemArray); + $this->assertResponseFields( + $productItemsInResponse[$itemIndex][0], + ['attribute_set_id' => $filteredProducts[$itemIndex]->getAttributeSetId(), + 'sku' => $filteredProducts[$itemIndex]->getSku(), + 'name' => $filteredProducts[$itemIndex]->getName(), + 'price' => [ + 'minimalPrice' => [ + 'amount' => [ + 'value' => $filteredProducts[$itemIndex]->getSpecialPrice(), + 'currency' => 'USD' + ] + ], + 'maximalPrice' => [ + 'amount' => [ + 'value' => $filteredProducts[$itemIndex]->getSpecialPrice(), + 'currency' => 'USD' + ] + ] + ], + 'type_id' =>$filteredProducts[$itemIndex]->getTypeId(), + 'weight' => $filteredProducts[$itemIndex]->getWeight() + ] + ); + } + } + /** * @param array $actualResponse * @param array $assertionMap ['response_field_name' => 'response_field_value', ...] diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php index 01d7da0eb39dd..eb0a7d3956c1b 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php @@ -21,9 +21,8 @@ */ class GraphQlReaderTest extends \PHPUnit\Framework\TestCase { - /** @var Config */ - private $model; + private $configModel; /** @var GraphQl */ private $graphQlController; @@ -34,7 +33,6 @@ class GraphQlReaderTest extends \PHPUnit\Framework\TestCase /** @var SerializerInterface */ private $jsonSerializer; - protected function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); @@ -44,31 +42,30 @@ protected function setUp() $fileResolverMock = $this->getMockBuilder( \Magento\Framework\Config\FileResolverInterface::class )->disableOriginalConstructor()->getMock(); - // $fileList = [file_get_contents(__DIR__ . '/../_files/schemaA.graphql')]; $fileList = [ - file_get_contents(__DIR__ . '/../_files/schemaA.graphql'), - file_get_contents(__DIR__ . '/../_files/schemaB.graphql') + file_get_contents(__DIR__ . '/../_files/schemaA.graphqls'), + file_get_contents(__DIR__ . '/../_files/schemaB.graphqls') ]; $fileResolverMock->expects($this->any())->method('get')->will($this->returnValue($fileList)); $graphQlReader = $this->objectManager->create( - \Magento\Framework\GraphQl\Config\GraphQlReader::class, + \Magento\Framework\GraphQlModularSchema\GraphQlReader::class, ['fileResolver' => $fileResolverMock] ); $reader = $this->objectManager->create( - \Magento\Framework\GraphQl\Config\Reader::class, - ['readers' => ['graphQlReader' => $graphQlReader]] + \Magento\Framework\GraphQlModularSchema\Reader::class, + ['readers' => ['graphql_reader' => $graphQlReader]] ); $data = $this->objectManager->create( \Magento\Framework\GraphQl\Config\Data ::class, ['reader' => $reader] ); - $this->model = $this->objectManager->create( + $this->configModel = $this->objectManager->create( \Magento\Framework\GraphQl\Config\Config::class, ['data' => $data] ); $graphQlSchemaProvider = $this->objectManager->create( \Magento\Framework\GraphQl\SchemaProvider::class, - ['config' =>$this->model] + ['config' =>$this->configModel] ); $typeGenerator = $this->objectManager->create( \Magento\GraphQl\Model\Type\Generator::class, diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphql b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphqls similarity index 100% rename from dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphql rename to dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphqls diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaB.graphql b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaB.graphqls similarity index 100% rename from dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaB.graphql rename to dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaB.graphqls From b78a546a657963bbea7e549c9171120e1b1631df Mon Sep 17 00:00:00 2001 From: Eugene Tulika Date: Tue, 27 Mar 2018 15:05:07 -0500 Subject: [PATCH 265/668] magento-engcom/bulk-api#4 Support for Async operations in WebAPI - Updated composer.json - Fixed wrong class reference --- .../Swagger/Controller/Index/Index.php | 4 +-- app/code/Magento/Swagger/composer.json | 2 +- app/code/Magento/SwaggerWebapi/composer.json | 2 +- .../Magento/SwaggerWebapiAsync/composer.json | 2 +- app/code/Magento/WebapiAsync/etc/di.xml | 36 ------------------- composer.json | 1 + composer.lock | 4 +-- .../Block/Swagger/IndexTest.php | 4 ++- 8 files changed, 11 insertions(+), 44 deletions(-) diff --git a/app/code/Magento/Swagger/Controller/Index/Index.php b/app/code/Magento/Swagger/Controller/Index/Index.php index 147466642f354..162367aaf81f9 100644 --- a/app/code/Magento/Swagger/Controller/Index/Index.php +++ b/app/code/Magento/Swagger/Controller/Index/Index.php @@ -23,8 +23,8 @@ class Index extends \Magento\Framework\App\Action\Action private $pageFactory; /** - * @param \Magento\Framework\App\Action\Context $context - * @param \Magento\Framework\View\Page\Config $pageConfig + * @param \Magento\Framework\App\Action\Context $context + * @param \Magento\Framework\View\Page\Config $pageConfig * @param \Magento\Framework\View\Result\PageFactory $pageFactory */ public function __construct( diff --git a/app/code/Magento/Swagger/composer.json b/app/code/Magento/Swagger/composer.json index 6c69bb08ef59f..9bacd69f161f5 100644 --- a/app/code/Magento/Swagger/composer.json +++ b/app/code/Magento/Swagger/composer.json @@ -10,7 +10,7 @@ "magento/module-webapi": "100.3.*" }, "type": "magento2-module", - "version": "100.0.0", + "version": "100.3.0-dev", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/SwaggerWebapi/composer.json b/app/code/Magento/SwaggerWebapi/composer.json index e5e8112f3f063..75a15ae984260 100644 --- a/app/code/Magento/SwaggerWebapi/composer.json +++ b/app/code/Magento/SwaggerWebapi/composer.json @@ -10,7 +10,7 @@ "magento/module-swagger": "100.3.*" }, "type": "magento2-module", - "version": "100.0.0", + "version": "100.3.0-dev", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/SwaggerWebapiAsync/composer.json b/app/code/Magento/SwaggerWebapiAsync/composer.json index acb4494355da7..435585e731f05 100644 --- a/app/code/Magento/SwaggerWebapiAsync/composer.json +++ b/app/code/Magento/SwaggerWebapiAsync/composer.json @@ -14,7 +14,7 @@ "magento/module-config": "100.3.*" }, "type": "magento2-module", - "version": "100.0.0", + "version": "100.3.0-dev", "license": [ "proprietary" ], diff --git a/app/code/Magento/WebapiAsync/etc/di.xml b/app/code/Magento/WebapiAsync/etc/di.xml index d2f984fae1cf8..7d289283ee028 100755 --- a/app/code/Magento/WebapiAsync/etc/di.xml +++ b/app/code/Magento/WebapiAsync/etc/di.xml @@ -7,43 +7,7 @@ --> - - - - - - - - - - - Magento\WebapiAsync\Model\MessageQueue\MassPublisher - Magento\WebapiAsync\Model\MessageQueue\MassPublisher - - - - - - - - Magento\WebapiAsync\VirtualType\PublisherPool - - - - - - Magento\WebapiAsync\VirtualType\BulkManagement - - - - diff --git a/composer.json b/composer.json index fe3fc5be1f506..f3b20c0a39810 100644 --- a/composer.json +++ b/composer.json @@ -206,6 +206,7 @@ "magento/module-store": "100.3.0-dev", "magento/module-swagger": "100.3.0-dev", "magento/module-swagger-webapi": "100.3.0-dev", + "magento/module-swagger-webapi-async": "100.3.0-dev", "magento/module-swatches": "100.3.0-dev", "magento/module-swatches-layered-navigation": "100.3.0-dev", "magento/module-tax": "100.3.0-dev", diff --git a/composer.lock b/composer.lock index ddaafe79cb081..6cc5a6fbb91f5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "bf103fd125d40bdeb82fd67bb34e46c0", - "content-hash": "de6c896a88703a9a9416cc7042892305", + "hash": "5d6eacb46240ccc5aa06c9ebdb8a27f3", + "content-hash": "aae540e9d7a72249f1d38888f28bf8c6", "packages": [ { "name": "braintree/braintree_php", diff --git a/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/IndexTest.php b/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/IndexTest.php index 97c5fa6590975..39a71da3e0acd 100644 --- a/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/IndexTest.php @@ -5,6 +5,8 @@ */ namespace Magento\SwaggerWebapiAsync\Block\Swagger; +use Magento\Swagger\Api\Data\SchemaTypeInterface; + /** * @magentoAppArea frontend */ @@ -28,7 +30,7 @@ protected function setUp() [ 'data' => [ 'schema_types' => \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Swagger\Api\Block\SchemaTypesInterface::class + SchemaTypeInterface::class ) ] ] From 2550e3d36befe3b2d7f98d919eb049534269adc5 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 27 Mar 2018 15:28:02 -0500 Subject: [PATCH 266/668] MAGETWO-89292: Implement SDL from prototype - rename --- app/code/Magento/CatalogGraphQl/etc/di.xml | 2 +- app/code/Magento/GraphQl/etc/di.xml | 20 +- app/code/Magento/GraphQl/etc/graphql.xsd | 263 ------------------ .../GraphQl/Config/GraphQlReaderTest.php | 4 +- .../Common/Reader.php | 2 +- .../GraphQlReader.php | 4 +- .../GraphQlReader/MetaReader/DocReader.php | 2 +- .../MetaReader/FieldMetaReader.php | 4 +- .../MetaReader/ImplementsReader.php | 2 +- .../MetaReader/TypeMetaWrapperReader.php | 2 +- .../GraphQlReader/Reader/EnumType.php | 6 +- .../GraphQlReader/Reader/InputObjectType.php | 8 +- .../GraphQlReader/Reader/InterfaceType.php | 8 +- .../GraphQlReader/Reader/ObjectType.php | 10 +- .../GraphQlReader/TypeMetaReaderInterface.php | 2 +- .../GraphQlReader/TypeReaderComposite.php | 2 +- 16 files changed, 39 insertions(+), 302 deletions(-) delete mode 100644 app/code/Magento/GraphQl/etc/graphql.xsd rename lib/internal/Magento/Framework/{GraphqlModularSchema => GraphQlModularSchema}/Common/Reader.php (93%) rename lib/internal/Magento/Framework/{GraphqlModularSchema => GraphQlModularSchema}/GraphQlReader.php (98%) rename lib/internal/Magento/Framework/{GraphqlModularSchema => GraphQlModularSchema}/GraphQlReader/MetaReader/DocReader.php (92%) rename lib/internal/Magento/Framework/{GraphqlModularSchema => GraphQlModularSchema}/GraphQlReader/MetaReader/FieldMetaReader.php (95%) rename lib/internal/Magento/Framework/{GraphqlModularSchema => GraphQlModularSchema}/GraphQlReader/MetaReader/ImplementsReader.php (94%) rename lib/internal/Magento/Framework/{GraphqlModularSchema => GraphQlModularSchema}/GraphQlReader/MetaReader/TypeMetaWrapperReader.php (96%) rename lib/internal/Magento/Framework/{GraphqlModularSchema => GraphQlModularSchema}/GraphQlReader/Reader/EnumType.php (87%) rename lib/internal/Magento/Framework/{GraphqlModularSchema => GraphQlModularSchema}/GraphQlReader/Reader/InputObjectType.php (88%) rename lib/internal/Magento/Framework/{GraphqlModularSchema => GraphQlModularSchema}/GraphQlReader/Reader/InterfaceType.php (89%) rename lib/internal/Magento/Framework/{GraphqlModularSchema => GraphQlModularSchema}/GraphQlReader/Reader/ObjectType.php (86%) rename lib/internal/Magento/Framework/{GraphqlModularSchema => GraphQlModularSchema}/GraphQlReader/TypeMetaReaderInterface.php (89%) rename lib/internal/Magento/Framework/{GraphqlModularSchema => GraphQlModularSchema}/GraphQlReader/TypeReaderComposite.php (93%) diff --git a/app/code/Magento/CatalogGraphQl/etc/di.xml b/app/code/Magento/CatalogGraphQl/etc/di.xml index dd0c7de52f00f..eaa7d667f8acb 100644 --- a/app/code/Magento/CatalogGraphQl/etc/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/di.xml @@ -20,7 +20,7 @@ - + Magento\CatalogGraphQl\Model\Config\AttributeReader diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 1fd95532ead14..43ef04f47cac3 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -11,7 +11,7 @@ - + @@ -35,8 +35,8 @@ - Magento\Framework\GraphQlModularSchema\Reader - Magento_Framework_GraphQlModularSchema_Config_Data + Magento\Framework\GraphQlSchemaStiching\Reader + Magento_Framework_GraphQlSchemaStiching_Config_Data @@ -44,10 +44,10 @@ urn:magento:module:Magento_GraphQl:etc/graphql.xsd - + - Magento\Framework\GraphQlModularSchema\GraphQlReader + Magento\Framework\GraphQlSchemaStiching\GraphQlReader @@ -83,13 +83,13 @@ - + - Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader\EnumType - Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader\ObjectType - Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader\InputObjectType - Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader\InterfaceType + Magento\Framework\GraphQlSchemaStiching\GraphQlReader\Reader\EnumType + Magento\Framework\GraphQlSchemaStiching\GraphQlReader\Reader\ObjectType + Magento\Framework\GraphQlSchemaStiching\GraphQlReader\Reader\InputObjectType + Magento\Framework\GraphQlSchemaStiching\GraphQlReader\Reader\InterfaceType diff --git a/app/code/Magento/GraphQl/etc/graphql.xsd b/app/code/Magento/GraphQl/etc/graphql.xsd deleted file mode 100644 index 6683574178136..0000000000000 --- a/app/code/Magento/GraphQl/etc/graphql.xsd +++ /dev/null @@ -1,263 +0,0 @@ - - - - - - Copyright © Magento, Inc. All rights reserved. - See COPYING.txt for license details. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - All input types must have "Input" suffix - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php index eb0a7d3956c1b..299d7cfa6ec4b 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php @@ -48,11 +48,11 @@ protected function setUp() ]; $fileResolverMock->expects($this->any())->method('get')->will($this->returnValue($fileList)); $graphQlReader = $this->objectManager->create( - \Magento\Framework\GraphQlModularSchema\GraphQlReader::class, + \Magento\Framework\GraphQlSchemaStiching\GraphQlReader::class, ['fileResolver' => $fileResolverMock] ); $reader = $this->objectManager->create( - \Magento\Framework\GraphQlModularSchema\Reader::class, + \Magento\Framework\GraphQlSchemaStiching\Reader::class, ['readers' => ['graphql_reader' => $graphQlReader]] ); $data = $this->objectManager->create( diff --git a/lib/internal/Magento/Framework/GraphqlModularSchema/Common/Reader.php b/lib/internal/Magento/Framework/GraphQlModularSchema/Common/Reader.php similarity index 93% rename from lib/internal/Magento/Framework/GraphqlModularSchema/Common/Reader.php rename to lib/internal/Magento/Framework/GraphQlModularSchema/Common/Reader.php index 3e6fd404c119d..895698c9bc0b1 100644 --- a/lib/internal/Magento/Framework/GraphqlModularSchema/Common/Reader.php +++ b/lib/internal/Magento/Framework/GraphQlModularSchema/Common/Reader.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\Framework\GraphQlModularSchema\Common; +namespace Magento\Framework\GraphQlSchemaStiching\Common; use Magento\Framework\Config\ReaderInterface; diff --git a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader.php similarity index 98% rename from lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader.php rename to lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader.php index 99134b37fc98c..c24abff12204a 100644 --- a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader.php +++ b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader.php @@ -5,10 +5,10 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQlModularSchema; +namespace Magento\Framework\GraphQlSchemaStiching; use Magento\Framework\Config\FileResolverInterface; -use Magento\Framework\GraphqlModularSchema\GraphQlReader\TypeMetaReaderInterface as TypeReaderComposite; +use Magento\Framework\GraphqlSchemaStiching\GraphQlReader\TypeMetaReaderInterface as TypeReaderComposite; use Magento\Framework\Config\ReaderInterface; /** diff --git a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/DocReader.php b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/DocReader.php similarity index 92% rename from lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/DocReader.php rename to lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/DocReader.php index bfe4d2e2b381b..a1f4a376adff3 100644 --- a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/DocReader.php +++ b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/DocReader.php @@ -5,7 +5,7 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader; +namespace Magento\Framework\GraphQlSchemaStiching\GraphQlReader\MetaReader; /** * Reads documentation from the annotation @doc of an AST node diff --git a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/FieldMetaReader.php b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/FieldMetaReader.php similarity index 95% rename from lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/FieldMetaReader.php rename to lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/FieldMetaReader.php index 67066bc3e8a99..33cfce2e10e80 100644 --- a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/FieldMetaReader.php +++ b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/FieldMetaReader.php @@ -5,9 +5,9 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader; +namespace Magento\Framework\GraphQlSchemaStiching\GraphQlReader\MetaReader; -use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\TypeMetaWrapperReader; +use Magento\Framework\GraphQlSchemaStiching\GraphQlReader\MetaReader\TypeMetaWrapperReader; /** * Reads fields and possible arguments from a meta field diff --git a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/ImplementsReader.php b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/ImplementsReader.php similarity index 94% rename from lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/ImplementsReader.php rename to lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/ImplementsReader.php index 23f5ebda03cdc..8e61705bb5748 100644 --- a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/ImplementsReader.php +++ b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/ImplementsReader.php @@ -5,7 +5,7 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader; +namespace Magento\Framework\GraphQlSchemaStiching\GraphQlReader\MetaReader; /** * Reads interfaces implementations from the annotation @implements of an AST node diff --git a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/TypeMetaWrapperReader.php b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/TypeMetaWrapperReader.php similarity index 96% rename from lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/TypeMetaWrapperReader.php rename to lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/TypeMetaWrapperReader.php index 3a899c3e24695..27a2bd81a9fdf 100644 --- a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/MetaReader/TypeMetaWrapperReader.php +++ b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/TypeMetaWrapperReader.php @@ -5,7 +5,7 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader; +namespace Magento\Framework\GraphQlSchemaStiching\GraphQlReader\MetaReader; /** * Common cases for types that need extra formatting like wrapping or additional properties added to their definition diff --git a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/EnumType.php b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/EnumType.php similarity index 87% rename from lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/EnumType.php rename to lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/EnumType.php index 4ac2fb341b8c0..ae03444e50761 100644 --- a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/EnumType.php +++ b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/EnumType.php @@ -5,10 +5,10 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader; +namespace Magento\Framework\GraphQlSchemaStiching\GraphQlReader\Reader; -use Magento\Framework\GraphQlModularSchema\GraphQlReader\TypeMetaReaderInterface; -use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\DocReader; +use Magento\Framework\GraphQlSchemaStiching\GraphQlReader\TypeMetaReaderInterface; +use Magento\Framework\GraphQlSchemaStiching\GraphQlReader\MetaReader\DocReader; /** * Composite configuration reader to handle the enum type meta diff --git a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/InputObjectType.php b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/InputObjectType.php similarity index 88% rename from lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/InputObjectType.php rename to lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/InputObjectType.php index df5349822d70f..598f68f0a0d74 100644 --- a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/InputObjectType.php @@ -5,11 +5,11 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader; +namespace Magento\Framework\GraphQlSchemaStiching\GraphQlReader\Reader; -use Magento\Framework\GraphQlModularSchema\GraphQlReader\TypeMetaReaderInterface; -use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\TypeMetaWrapperReader; -use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\DocReader; +use Magento\Framework\GraphQlSchemaStiching\GraphQlReader\TypeMetaReaderInterface; +use Magento\Framework\GraphQlSchemaStiching\GraphQlReader\MetaReader\TypeMetaWrapperReader; +use Magento\Framework\GraphQlSchemaStiching\GraphQlReader\MetaReader\DocReader; /** * Composite configuration reader to handle the input object type meta diff --git a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/InterfaceType.php b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/InterfaceType.php similarity index 89% rename from lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/InterfaceType.php rename to lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/InterfaceType.php index 340623920d431..b408ed51e45b0 100644 --- a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/InterfaceType.php +++ b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/InterfaceType.php @@ -5,11 +5,11 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader; +namespace Magento\Framework\GraphQlSchemaStiching\GraphQlReader\Reader; -use Magento\Framework\GraphQlModularSchema\GraphQlReader\TypeMetaReaderInterface; -use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\FieldMetaReader; -use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\DocReader; +use Magento\Framework\GraphQlSchemaStiching\GraphQlReader\TypeMetaReaderInterface; +use Magento\Framework\GraphQlSchemaStiching\GraphQlReader\MetaReader\FieldMetaReader; +use Magento\Framework\GraphQlSchemaStiching\GraphQlReader\MetaReader\DocReader; /** * Composite configuration reader to handle the interface object type meta diff --git a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/ObjectType.php similarity index 86% rename from lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/ObjectType.php rename to lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/ObjectType.php index 7adeb89afb15f..72949e4b3a921 100644 --- a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/Reader/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/ObjectType.php @@ -5,12 +5,12 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQlModularSchema\GraphQlReader\Reader; +namespace Magento\Framework\GraphQlSchemaStiching\GraphQlReader\Reader; -use Magento\Framework\GraphQlModularSchema\GraphQlReader\TypeMetaReaderInterface; -use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\FieldMetaReader; -use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\DocReader; -use Magento\Framework\GraphQlModularSchema\GraphQlReader\MetaReader\ImplementsReader; +use Magento\Framework\GraphQlSchemaStiching\GraphQlReader\TypeMetaReaderInterface; +use Magento\Framework\GraphQlSchemaStiching\GraphQlReader\MetaReader\FieldMetaReader; +use Magento\Framework\GraphQlSchemaStiching\GraphQlReader\MetaReader\DocReader; +use Magento\Framework\GraphQlSchemaStiching\GraphQlReader\MetaReader\ImplementsReader; /** * Composite configuration reader to handle the object type meta diff --git a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/TypeMetaReaderInterface.php b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/TypeMetaReaderInterface.php similarity index 89% rename from lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/TypeMetaReaderInterface.php rename to lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/TypeMetaReaderInterface.php index 9e9e68e9c077f..01ef71e6308c9 100644 --- a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/TypeMetaReaderInterface.php +++ b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/TypeMetaReaderInterface.php @@ -5,7 +5,7 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQlModularSchema\GraphQlReader; +namespace Magento\Framework\GraphQlSchemaStiching\GraphQlReader; /** * Reads and returns metadata as array for a specific type if it finds an adequate implementation for that type diff --git a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/TypeReaderComposite.php b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/TypeReaderComposite.php similarity index 93% rename from lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/TypeReaderComposite.php rename to lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/TypeReaderComposite.php index d7b500056c8cc..98dc30db2d9f0 100644 --- a/lib/internal/Magento/Framework/GraphqlModularSchema/GraphQlReader/TypeReaderComposite.php +++ b/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/TypeReaderComposite.php @@ -5,7 +5,7 @@ */ declare(strict_types = 1); -namespace Magento\Framework\GraphQlModularSchema\GraphQlReader; +namespace Magento\Framework\GraphQlSchemaStiching\GraphQlReader; /** * Composite configured class used to determine which reader should be used for a specific type From ccd084ec44a23c0d2bbff2bd0df6d1965375ddb6 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 27 Mar 2018 15:52:00 -0500 Subject: [PATCH 267/668] MAGETWO-89292: Implement SDL from prototype - rename --- .../Test/Unit/Model/Config/XsdTest.php | 63 ---- .../_files/graphql_simple_configurable.xml | 275 ------------------ .../Config/_files/invalidGraphQlXmlArray.php | 235 --------------- .../Common/Reader.php | 0 .../GraphQlReader.php | 0 .../GraphQlReader/MetaReader/DocReader.php | 0 .../MetaReader/FieldMetaReader.php | 0 .../MetaReader/ImplementsReader.php | 0 .../MetaReader/TypeMetaWrapperReader.php | 0 .../GraphQlReader/Reader/EnumType.php | 0 .../GraphQlReader/Reader/InputObjectType.php | 0 .../GraphQlReader/Reader/InterfaceType.php | 0 .../GraphQlReader/Reader/ObjectType.php | 0 .../GraphQlReader/TypeMetaReaderInterface.php | 0 .../GraphQlReader/TypeReaderComposite.php | 0 15 files changed, 573 deletions(-) delete mode 100644 app/code/Magento/GraphQl/Test/Unit/Model/Config/XsdTest.php delete mode 100644 app/code/Magento/GraphQl/Test/Unit/Model/Config/_files/graphql_simple_configurable.xml delete mode 100644 app/code/Magento/GraphQl/Test/Unit/Model/Config/_files/invalidGraphQlXmlArray.php rename lib/internal/Magento/Framework/{GraphQlModularSchema => GraphQlSchemaStiching}/Common/Reader.php (100%) rename lib/internal/Magento/Framework/{GraphQlModularSchema => GraphQlSchemaStiching}/GraphQlReader.php (100%) rename lib/internal/Magento/Framework/{GraphQlModularSchema => GraphQlSchemaStiching}/GraphQlReader/MetaReader/DocReader.php (100%) rename lib/internal/Magento/Framework/{GraphQlModularSchema => GraphQlSchemaStiching}/GraphQlReader/MetaReader/FieldMetaReader.php (100%) rename lib/internal/Magento/Framework/{GraphQlModularSchema => GraphQlSchemaStiching}/GraphQlReader/MetaReader/ImplementsReader.php (100%) rename lib/internal/Magento/Framework/{GraphQlModularSchema => GraphQlSchemaStiching}/GraphQlReader/MetaReader/TypeMetaWrapperReader.php (100%) rename lib/internal/Magento/Framework/{GraphQlModularSchema => GraphQlSchemaStiching}/GraphQlReader/Reader/EnumType.php (100%) rename lib/internal/Magento/Framework/{GraphQlModularSchema => GraphQlSchemaStiching}/GraphQlReader/Reader/InputObjectType.php (100%) rename lib/internal/Magento/Framework/{GraphQlModularSchema => GraphQlSchemaStiching}/GraphQlReader/Reader/InterfaceType.php (100%) rename lib/internal/Magento/Framework/{GraphQlModularSchema => GraphQlSchemaStiching}/GraphQlReader/Reader/ObjectType.php (100%) rename lib/internal/Magento/Framework/{GraphQlModularSchema => GraphQlSchemaStiching}/GraphQlReader/TypeMetaReaderInterface.php (100%) rename lib/internal/Magento/Framework/{GraphQlModularSchema => GraphQlSchemaStiching}/GraphQlReader/TypeReaderComposite.php (100%) diff --git a/app/code/Magento/GraphQl/Test/Unit/Model/Config/XsdTest.php b/app/code/Magento/GraphQl/Test/Unit/Model/Config/XsdTest.php deleted file mode 100644 index 673312618a3bc..0000000000000 --- a/app/code/Magento/GraphQl/Test/Unit/Model/Config/XsdTest.php +++ /dev/null @@ -1,63 +0,0 @@ -markTestSkipped('Skipped on HHVM. Will be fixed in MAGETWO-45033'); - } - $urnResolver = new \Magento\Framework\Config\Dom\UrnResolver(); - $this->xsdSchema = $urnResolver->getRealPath('urn:magento:module:Magento_GraphQl:etc/graphql.xsd'); - $this->xsdValidator = new \Magento\Framework\TestFramework\Unit\Utility\XsdValidator(); - } - - /** - * @param string $xmlString - * @param array $expectedError - * @return void - * @dataProvider schemaCorrectlyIdentifiesInvalidXmlDataProvider - */ - public function testSchemaCorrectlyIdentifiesInvalidXml($xmlString, $expectedError) : void - { - $actualError = $this->xsdValidator->validate($this->xsdSchema, $xmlString); - $this->assertEquals($expectedError, $actualError); - } - - /** - * @return void - */ - public function testSchemaCorrectlyIdentifiesValidXml() : void - { - $xmlString = file_get_contents(__DIR__ . '/_files/graphql_simple_configurable.xml'); - $actualResult = $this->xsdValidator->validate($this->xsdSchema, $xmlString); - $this->assertEmpty($actualResult); - } - - /** - * Data provider with invalid xml array according to graphql.xsd - * @return array - */ - public function schemaCorrectlyIdentifiesInvalidXmlDataProvider() : array - { - return include __DIR__ . '/_files/invalidGraphQlXmlArray.php'; - } -} diff --git a/app/code/Magento/GraphQl/Test/Unit/Model/Config/_files/graphql_simple_configurable.xml b/app/code/Magento/GraphQl/Test/Unit/Model/Config/_files/graphql_simple_configurable.xml deleted file mode 100644 index 9b4e637edf675..0000000000000 --- a/app/code/Magento/GraphQl/Test/Unit/Model/Config/_files/graphql_simple_configurable.xml +++ /dev/null @@ -1,275 +0,0 @@ - - - - - - - - - - - - - - USD - EUR - CAD - - - - Tax - Wee - WeeTax - - - - Included - Excluded - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/code/Magento/GraphQl/Test/Unit/Model/Config/_files/invalidGraphQlXmlArray.php b/app/code/Magento/GraphQl/Test/Unit/Model/Config/_files/invalidGraphQlXmlArray.php deleted file mode 100644 index 8c068bcb2badb..0000000000000 --- a/app/code/Magento/GraphQl/Test/Unit/Model/Config/_files/invalidGraphQlXmlArray.php +++ /dev/null @@ -1,235 +0,0 @@ - [ - ' - - - Hello - - - ', - [ - - ], - ], - 'type_InputType_with_invalid_attribute' => [ - ' - ', - [ - "Element 'type', attribute 'summary': The attribute 'summary' is" . - " not allowed.\nLine: 2\n" - ], - ], - 'field_with_no_type_element' => [ - ' - - - ', - [ - "Element 'field': This element is not expected. Expected is ( type ).\nLine: 2\n" - ], - ], - 'missing_abstract_type_definition' => [ - ' - ', - [ - "Element 'type': The type definition is abstract.\nLine: 2\n" - ], - ], - 'type_enum_with_no_required_name_attribute' => [ - ' - someValue', - [ - "Element 'type': The attribute 'name' is required but missing.\n" . - "Line: 2\n" - ], - ], - 'type_EnumItem_with_no_required_attribute' => [ - ' - text1', - [ - "Element 'item': The attribute 'name' is required but missing.\n" . - "Line: 2\n" - ], - ], - 'type_OutputType_with_missing_interface_field_attribute' => [ - ' - - - ', - [ - "Element 'implements': The attribute 'interface' is required but missing.\n" . - "Line: 3\n" - ], - ], - 'type_OutputType_with__no_xsi_type_attribute' => [ - ' - - - - ', - [ - "Element 'field': The type definition is abstract.\n" . - "Line: 4\n" - ], - ], - 'type_OutputInterface_with_missing_name_and_typeResolver_attribute' => [ - ' - ', - [ - "Element 'type': The attribute 'name' is required but missing.\n" . - "Line: 2\n" - ], - ], - 'type_InputType_with_missing_required_name_attribute' => [ - ' - ', - [ - "Element 'type': The attribute 'name' is required but missing.\n" . - "Line: 2\n" - ], - ], - 'type_InputType_with_incompatible_name_attribute_value' => [ - ' - ', - [ - "Element 'type', attribute 'name': [facet 'pattern'] The value 'ProductSort' is not accepted by the" . - " pattern '.*Input'.\nLine: 2\n", - "Element 'type', attribute 'name': 'ProductSort' is not a valid value of the atomic type" . - " 'InputTypeNameType'.\nLine: 2\n" - ], - ], - 'type_InputType_with_incompatible_enum_value_for_scalarInput_field' => [ - ' - - - ', - [ - "Element 'field', attribute 'type': [facet 'enumeration'] The value 'Decimal' is not an element of the" . - " set {'Int', 'String', 'Boolean', 'Float'}.\nLine: 3\n", - "Element 'field', attribute 'type': 'Decimal' is not a valid value of the" . - " atomic type 'GraphQlScalarTypesEnum'.\nLine: 3\n" - ], - ], - 'type_InputType_with_invalid_enum_value_for_scalarOutput_field_and_invalid_field_attribute_value' => [ - ' - - - - ', - [ - "Element 'field', attribute 'type': [facet 'enumeration'] The value 'string' is" . - " not an element of the set {'Int', 'String', 'Boolean', 'Float'}.\nLine: 4\n", - "Element 'field', attribute 'type': 'string' is not a valid value of the" . - " atomic type 'GraphQlScalarTypesEnum'.\nLine: 4\n", - "Element 'field', attribute 'required': 'yes' is not a valid value of the atomic" . - " type 'xs:boolean'.\nLine: 4\n" - ], - ], - 'type_InputType_field_ScalarOutput_with_missing_name_attribute_for_ScalarArgument' => [ - ' - - - - - ', - [ - "Element 'argument': The attribute 'type' is required but missing.\nLine: 5\n", - "Element 'argument': The attribute 'name' is required but missing.\nLine: 5\n" - ], - ], - 'type_OutType_with_ScalarArrayInputField_with_argument_node_not_allowed' => [ - ' - - - - ', - [ - "Element 'field': Character content is not allowed, because the content type is empty.\nLine: 3\n", - "Element 'field': Element content is not allowed, because the content type is empty.\nLine: 3\n" - ], - ], - 'argument_ObjectArrayArgument_with_missing_name_and_itemType' => [ - ' - - - - - - ', - [ - "Element 'argument', attribute 'required': '' is not a valid value of" . - " the atomic type 'xs:boolean'.\nLine: 4\n", - "Element 'argument': The attribute 'itemType' is required but missing.\nLine: 6\n", - "Element 'argument': The attribute 'name' is required but missing.\nLine: 6\n" - ], - ], - 'type_OutputType_with_missing_name_attribute' => [ - ' - - - ', - [ - "Element 'type': The attribute 'name' is required but missing.\n" . - "Line: 2\n" - ], - ], - 'argument_SortArgument_with_missing_baseType' => [ - ' - Testing if cdata is allowed - - - - - - ', - [ - "Element 'argument': The attribute 'baseType' is required but missing.\nLine: 11\n" - ], - ], - 'invalid_argument_FilterArgument_with missing baseType attribute' => [ - ' - - - - - - - - - ', - [ - "Element 'argument', attribute 'Filter': The attribute 'Filter' is not allowed.\nLine: 9\n", - "Element 'argument': The attribute 'baseType' is required but missing.\nLine: 9\n" - ], - ], - 'cdata_not_allowed_with_type_or_field_element' => [ - ' - Testing if cdata is allowed with type - - Testing if cdata is allowed with argument - - - - ', - [ - "Element 'type': Character content other than whitespace is not allowed because the" . - " content type is 'element-only'.\nLine: 2\n", - "Element 'field': Character content other than whitespace is not allowed because the" . - " content type is 'element-only'.\nLine: 3\n" - ], - ] -]; diff --git a/lib/internal/Magento/Framework/GraphQlModularSchema/Common/Reader.php b/lib/internal/Magento/Framework/GraphQlSchemaStiching/Common/Reader.php similarity index 100% rename from lib/internal/Magento/Framework/GraphQlModularSchema/Common/Reader.php rename to lib/internal/Magento/Framework/GraphQlSchemaStiching/Common/Reader.php diff --git a/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader.php b/lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader.php similarity index 100% rename from lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader.php rename to lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader.php diff --git a/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/DocReader.php b/lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/MetaReader/DocReader.php similarity index 100% rename from lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/DocReader.php rename to lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/MetaReader/DocReader.php diff --git a/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/FieldMetaReader.php b/lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/MetaReader/FieldMetaReader.php similarity index 100% rename from lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/FieldMetaReader.php rename to lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/MetaReader/FieldMetaReader.php diff --git a/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/ImplementsReader.php b/lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/MetaReader/ImplementsReader.php similarity index 100% rename from lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/ImplementsReader.php rename to lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/MetaReader/ImplementsReader.php diff --git a/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/TypeMetaWrapperReader.php b/lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/MetaReader/TypeMetaWrapperReader.php similarity index 100% rename from lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/MetaReader/TypeMetaWrapperReader.php rename to lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/MetaReader/TypeMetaWrapperReader.php diff --git a/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/EnumType.php b/lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/Reader/EnumType.php similarity index 100% rename from lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/EnumType.php rename to lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/Reader/EnumType.php diff --git a/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/InputObjectType.php b/lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/Reader/InputObjectType.php similarity index 100% rename from lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/InputObjectType.php rename to lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/Reader/InputObjectType.php diff --git a/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/InterfaceType.php b/lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/Reader/InterfaceType.php similarity index 100% rename from lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/InterfaceType.php rename to lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/Reader/InterfaceType.php diff --git a/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/Reader/ObjectType.php similarity index 100% rename from lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/Reader/ObjectType.php rename to lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/Reader/ObjectType.php diff --git a/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/TypeMetaReaderInterface.php b/lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/TypeMetaReaderInterface.php similarity index 100% rename from lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/TypeMetaReaderInterface.php rename to lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/TypeMetaReaderInterface.php diff --git a/lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/TypeReaderComposite.php b/lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/TypeReaderComposite.php similarity index 100% rename from lib/internal/Magento/Framework/GraphQlModularSchema/GraphQlReader/TypeReaderComposite.php rename to lib/internal/Magento/Framework/GraphQlSchemaStiching/GraphQlReader/TypeReaderComposite.php From 9ef6c2c46a5c3b5deb9c1eab3871d25e476b0241 Mon Sep 17 00:00:00 2001 From: Eric Bohanon Date: Tue, 27 Mar 2018 16:06:06 -0500 Subject: [PATCH 268/668] MAGETWO-88936: Check security concerns --- lib/internal/Magento/Framework/GraphQl/QueryProcessor.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php index 2d82d8961c842..d609fb35eddca 100644 --- a/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php @@ -8,6 +8,7 @@ namespace Magento\Framework\GraphQl; use GraphQL\Validator\DocumentValidator; +use GraphQL\Validator\Rules\DisableIntrospection; use GraphQL\Validator\Rules\QueryDepth; use Magento\Framework\GraphQl\Type\Schema; @@ -48,8 +49,10 @@ public function process( $variableValues = null, $operationName = null ) { - $rule = new QueryDepth(10); - DocumentValidator::addRule($rule); + if (!$this->exceptionFormatter->shouldShowDetail()) { + DocumentValidator::addRule(new QueryDepth(10)); + DocumentValidator::addRule(new DisableIntrospection()); + } return \GraphQL\GraphQL::executeQuery( $schema, $source, From 566960501921ac1f43b554ac93eb0081fdaadf17 Mon Sep 17 00:00:00 2001 From: Eugene Tulika Date: Tue, 27 Mar 2018 16:14:56 -0500 Subject: [PATCH 269/668] magento-engcom/bulk-api#4 Support for Async operations in WebAPI - Removed outdated test --- .../Block/Swagger/IndexTest.php | 65 ------------------- 1 file changed, 65 deletions(-) delete mode 100644 dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/IndexTest.php diff --git a/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/IndexTest.php b/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/IndexTest.php deleted file mode 100644 index 39a71da3e0acd..0000000000000 --- a/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/IndexTest.php +++ /dev/null @@ -1,65 +0,0 @@ -get(\Magento\Framework\App\State::class) - ->setAreaCode('frontend'); - - $this->block = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Framework\View\LayoutInterface::class - )->createBlock( - \Magento\Swagger\Block\Index::class, - '', - [ - 'data' => [ - 'schema_types' => \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - SchemaTypeInterface::class - ) - ] - ] - ); - } - - /** - * Test that Swagger UI outputs the all store code when it is specified. - */ - public function testSchemaUrlOutput() - { - $this->block->getRequest()->setParams([ - 'type' => 'async', - 'store' => 'custom', - ]); - - $this->assertStringEndsWith('/async/all/schema?services=all', $this->block->getSchemaUrl()); - } - - /** - * Test that Swagger UI outputs the supplied store code when it is specified. - */ - public function testSchemaUrlOutputWithStore() - { - $this->block->getRequest()->setParams([ - 'type' => 'async', - 'store' => 'custom', - ]); - - $this->assertStringEndsWith('/async/custom/schema?services=all', $this->block->getSchemaUrl()); - } -} From 3d379f18d6ec08cd155811d99666c861f5835297 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 27 Mar 2018 16:37:58 -0500 Subject: [PATCH 270/668] MAGETWO-89292: Implement SDL from prototype - rename --- app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls b/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls index 1303f5625d1a2..bd8964f06155f 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls +++ b/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls @@ -23,7 +23,7 @@ type ConfigurableProductOptions { attribute_code: String @doc(description: "A string that identifies the attribute") label: String @doc(description: "A string that describes the configurable product option. It is displayed on the UI.") position: Int @doc(description: "A number that indicates the order in which the attribute is displayed") - is_use_default: Boolean @doc(description: "Indicates whether the option is the default") + use_default: Boolean @doc(description: "Indicates whether the option is the default") values: [ConfigurableProductOptionsValues] @doc(description: "An array that defines the value_index codes assigned to the configurable product") product_id: Int @doc(description: "This is the same as a product's 'id' field") } From 0ac8ea89d9261b6afa48bdddb43ce9e146734496 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 27 Mar 2018 17:03:42 -0500 Subject: [PATCH 271/668] MAGETWO-89292: Implement SDL from prototype - fix test modules --- .../TestModuleGraphQlQuery/etc/graphql.xml | 16 ---------------- .../TestModuleGraphQlQuery/etc/schema.graphqls | 10 ++++++++++ .../etc/graphql.xml | 10 ---------- .../etc/schema.graphqls | 6 ++++++ 4 files changed, 16 insertions(+), 26 deletions(-) delete mode 100644 dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/etc/graphql.xml create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/etc/schema.graphqls delete mode 100644 dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/etc/graphql.xml create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/etc/schema.graphqls diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/etc/graphql.xml b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/etc/graphql.xml deleted file mode 100644 index 5d71c0d8f97fc..0000000000000 --- a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/etc/graphql.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/etc/schema.graphqls b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/etc/schema.graphqls new file mode 100644 index 0000000000000..8dbef582ff1ac --- /dev/null +++ b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQuery/etc/schema.graphqls @@ -0,0 +1,10 @@ +# Copyright © Magento, Inc. All rights reserved. +# See COPYING.txt for license details. + +type Query { + testItem(id: Int!) : Item @resolver(class: "Magento\\TestModuleGraphQlQuery\\Model\\Resolver\\Item") +} +type Item { + item_id: Int + name: String +} diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/etc/graphql.xml b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/etc/graphql.xml deleted file mode 100644 index bc834a98d379a..0000000000000 --- a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/etc/graphql.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/etc/schema.graphqls b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/etc/schema.graphqls new file mode 100644 index 0000000000000..ae99d5ac27629 --- /dev/null +++ b/dev/tests/api-functional/_files/Magento/TestModuleGraphQlQueryExtension/etc/schema.graphqls @@ -0,0 +1,6 @@ +# Copyright © Magento, Inc. All rights reserved. +# See COPYING.txt for license details. + +type Item { + integer_list: [Int] +} From 13eac481ca02e93928a2876c69d2dce8903575a0 Mon Sep 17 00:00:00 2001 From: Robert He Date: Tue, 27 Mar 2018 17:08:24 -0500 Subject: [PATCH 272/668] MAGETWO-89656: Add UI Component color modes - added color mode presets --- .../Ui/Component/Form/Element/ColorPicker.php | 71 +++++++++++++++++++ .../Model/ColorPicker/ColorModesProvider.php | 56 +++++++++++++++ .../Magento/Ui/Model/ColorPicker/FullMode.php | 32 +++++++++ .../Ui/Model/ColorPicker/ModeInterface.php | 22 ++++++ .../Ui/Model/ColorPicker/NoAlphaMode.php | 32 +++++++++ .../Ui/Model/ColorPicker/PaletteOnlyMode.php | 32 +++++++++ .../Ui/Model/ColorPicker/SimpleMode.php | 32 +++++++++ app/code/Magento/Ui/etc/adminhtml/di.xml | 10 +++ app/code/Magento/Ui/etc/ui_configuration.xsd | 15 ++-- .../base/ui_component/etc/definition.map.xml | 10 ++- .../view/base/ui_component/etc/definition.xml | 9 ++- .../etc/definition/colorPicker.xsd | 28 +++++++- .../base/web/js/form/element/colorPicker.js | 17 ++--- .../web/css/source/module/spectrum.less | 6 +- 14 files changed, 351 insertions(+), 21 deletions(-) create mode 100644 app/code/Magento/Ui/Component/Form/Element/ColorPicker.php create mode 100644 app/code/Magento/Ui/Model/ColorPicker/ColorModesProvider.php create mode 100644 app/code/Magento/Ui/Model/ColorPicker/FullMode.php create mode 100644 app/code/Magento/Ui/Model/ColorPicker/ModeInterface.php create mode 100644 app/code/Magento/Ui/Model/ColorPicker/NoAlphaMode.php create mode 100644 app/code/Magento/Ui/Model/ColorPicker/PaletteOnlyMode.php create mode 100644 app/code/Magento/Ui/Model/ColorPicker/SimpleMode.php diff --git a/app/code/Magento/Ui/Component/Form/Element/ColorPicker.php b/app/code/Magento/Ui/Component/Form/Element/ColorPicker.php new file mode 100644 index 0000000000000..0774aec355c80 --- /dev/null +++ b/app/code/Magento/Ui/Component/Form/Element/ColorPicker.php @@ -0,0 +1,71 @@ +modesProvider = $modesProvider; + parent::__construct($context, $components, $data); + } + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + $modes = $this->modesProvider->getModes(); + $colorPickerModeSetting = $this->getData('config/colorPickerMode'); + $colorFormatSetting = $this->getData('config/colorFormat'); + $colorPickerMode = $modes[$colorPickerModeSetting] ?? $modes[self::DEFAULT_MODE]; + $colorPickerMode['preferredFormat'] = $colorFormatSetting; + $this->_data['config']['colorPickerConfig'] = $colorPickerMode; + + parent::prepare(); + + } +} diff --git a/app/code/Magento/Ui/Model/ColorPicker/ColorModesProvider.php b/app/code/Magento/Ui/Model/ColorPicker/ColorModesProvider.php new file mode 100644 index 0000000000000..eeb7794bc60d9 --- /dev/null +++ b/app/code/Magento/Ui/Model/ColorPicker/ColorModesProvider.php @@ -0,0 +1,56 @@ +colorModes = $colorModesPool; + $this->objectManager = $objectManager; + } + + public function getModes() + { + $config = []; + foreach ($this->colorModes as $modeName => $className) { + $config[$modeName] = $this->createModeProvider($className)->getConfig(); + } + + return $config; + } + + /** + * Create mode provider + * + * @param string $instance + * @return ConfigInterface + */ + private function createModeProvider($instance) + { + if (!is_subclass_of( + $instance, + ModeInterface::class + ) + ) { + throw new \InvalidArgumentException( + $instance . + ' does not implement ' . + ModeInterface::class + ); + } + return $this->objectManager->create($instance); + } +} diff --git a/app/code/Magento/Ui/Model/ColorPicker/FullMode.php b/app/code/Magento/Ui/Model/ColorPicker/FullMode.php new file mode 100644 index 0000000000000..4d248435cf6ee --- /dev/null +++ b/app/code/Magento/Ui/Model/ColorPicker/FullMode.php @@ -0,0 +1,32 @@ + true, + 'allowEmpty' => false, + 'showInitial' => false, + 'showPalette' => true, + 'showAlpha' => false, + 'showSelectionPalette' => true + ]; + } +} diff --git a/app/code/Magento/Ui/Model/ColorPicker/ModeInterface.php b/app/code/Magento/Ui/Model/ColorPicker/ModeInterface.php new file mode 100644 index 0000000000000..b724a3abc7376 --- /dev/null +++ b/app/code/Magento/Ui/Model/ColorPicker/ModeInterface.php @@ -0,0 +1,22 @@ + true, + 'allowEmpty' => false, + 'showInitial' => false, + 'showPalette' => true, + 'showAlpha' => false, + 'showSelectionPalette' => true + ]; + } +} diff --git a/app/code/Magento/Ui/Model/ColorPicker/PaletteOnlyMode.php b/app/code/Magento/Ui/Model/ColorPicker/PaletteOnlyMode.php new file mode 100644 index 0000000000000..042df3b1f8c08 --- /dev/null +++ b/app/code/Magento/Ui/Model/ColorPicker/PaletteOnlyMode.php @@ -0,0 +1,32 @@ + false, + 'allowEmpty' => false, + 'showInitial' => false, + 'showPalette' => true, + 'showAlpha' => false, + 'showSelectionPalette' => true + ]; + } +} diff --git a/app/code/Magento/Ui/Model/ColorPicker/SimpleMode.php b/app/code/Magento/Ui/Model/ColorPicker/SimpleMode.php new file mode 100644 index 0000000000000..c1596c3b251ad --- /dev/null +++ b/app/code/Magento/Ui/Model/ColorPicker/SimpleMode.php @@ -0,0 +1,32 @@ + false, + 'allowEmpty' => false, + 'showInitial' => false, + 'showPalette' => false, + 'showAlpha' => false, + 'showSelectionPalette' => true + ]; + } +} diff --git a/app/code/Magento/Ui/etc/adminhtml/di.xml b/app/code/Magento/Ui/etc/adminhtml/di.xml index 416d7a6916f88..e5d09f228a4b7 100644 --- a/app/code/Magento/Ui/etc/adminhtml/di.xml +++ b/app/code/Magento/Ui/etc/adminhtml/di.xml @@ -44,4 +44,14 @@ + + + + Magento\Ui\Model\ColorPicker\FullMode + Magento\Ui\Model\ColorPicker\SimpleMode + Magento\Ui\Model\ColorPicker\NoAlphaMode + Magento\Ui\Model\ColorPicker\PaletteOnlyMode + + + diff --git a/app/code/Magento/Ui/etc/ui_configuration.xsd b/app/code/Magento/Ui/etc/ui_configuration.xsd index 7dc71a2c9a94f..32e8455ee1c71 100644 --- a/app/code/Magento/Ui/etc/ui_configuration.xsd +++ b/app/code/Magento/Ui/etc/ui_configuration.xsd @@ -451,6 +451,14 @@ + + + + The ColorPicker component utilizes the Spectrum js library to allow user greater flexibility in entering + color values. + + + @@ -783,11 +791,4 @@ - - - - ColorPicker - - - diff --git a/app/code/Magento/Ui/view/base/ui_component/etc/definition.map.xml b/app/code/Magento/Ui/view/base/ui_component/etc/definition.map.xml index c55c4cff76316..f8d6f85ded5db 100644 --- a/app/code/Magento/Ui/view/base/ui_component/etc/definition.map.xml +++ b/app/code/Magento/Ui/view/base/ui_component/etc/definition.map.xml @@ -107,7 +107,9 @@ - settings/initialCOlor + settings/initialColor + settings/colorPickerMode + settings/colorFormat @@ -296,6 +298,12 @@ @formElement + + formElements/*[name(.)=../../@formElement]/settings/colorPickerMode + + + formElements/*[name(.)=../../@formElement]/settings/colorFormat + formElements/*[name(.)=../../@formElement]/settings/wysiwyg diff --git a/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml index 48c7c8951ab08..2a334aba6a9cd 100755 --- a/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml +++ b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml @@ -149,7 +149,14 @@ wysiwyg - + + + rgb(0,0,0) + rgb + full + + + diff --git a/app/code/Magento/Ui/view/base/ui_component/etc/definition/colorPicker.xsd b/app/code/Magento/Ui/view/base/ui_component/etc/definition/colorPicker.xsd index 9ae157b2028ac..17942160f9552 100644 --- a/app/code/Magento/Ui/view/base/ui_component/etc/definition/colorPicker.xsd +++ b/app/code/Magento/Ui/view/base/ui_component/etc/definition/colorPicker.xsd @@ -6,7 +6,6 @@ */ --> - @@ -15,7 +14,7 @@ - + @@ -23,9 +22,32 @@ - + + + + + Defines the initial color that appears in the color selection dropdown and input field. + + + + + + + Defines the color format that is displayed in selection tool as well as in input field. + Valid formats: hex, rgb, hsl, hsv + + + + + + + Defines the mode that affects available color picker functionality + Valid modes: simple, full, noalpha, palette + + + diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/colorPicker.js b/app/code/Magento/Ui/view/base/web/js/form/element/colorPicker.js index b3fb0429d880f..e03053c8dce7a 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/colorPicker.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/colorPicker.js @@ -27,20 +27,21 @@ define([ defaults: { colorPickerConfig: { - showInput: true, - allowEmpty: true, - showInitial: false, - showPalette: true, - showAlpha: true, chooseText: "Apply", cancelText: "Cancel", - showSelectionPalette: true, - maxSelectionSize: 64, - preferredFormat: "rgb", + maxSelectionSize: 8, + clickoutFiresChange: true, palette: defaultColorPalette } }, + initConfig: function (config) { + this._super(); + + this.constructor.defaults.colorPickerConfig = Object.assign(this.constructor.defaults.colorPickerConfig, config.colorPickerConfig); + return this; + }, + /** * Initializes observable properties of instance * diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/spectrum.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/spectrum.less index 89880abda1d84..59f7bf18dfb9e 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/spectrum.less +++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/spectrum.less @@ -386,11 +386,11 @@ See http://bgrins.github.io/spectrum/themes/ for instructions. color: silver; } .sp-dd { - padding: 2px 0; height: 16px; line-height: 16px; float:left; font-size:10px; + display: none; } .sp-preview { position:relative; @@ -506,3 +506,7 @@ See http://bgrins.github.io/spectrum/themes/ for instructions. background-position: center; background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==); } + +.sp-palette-row-selection { + padding-top: 25px; +} From 371f959534d6a7507ada651afe14d1ebc4f2f1f0 Mon Sep 17 00:00:00 2001 From: Eugene Tulika Date: Tue, 27 Mar 2018 18:49:58 -0500 Subject: [PATCH 273/668] magento-engcom/bulk-api#4 Support for Async operations in WebAPI - Removed outdated test - Returned correct preference --- .../Model/BulkStatus.php | 8 ++-- .../Magento/AsynchronousOperations/etc/di.xml | 1 + .../Block/Swagger/SchemaTypesTest.php | 45 ------------------- 3 files changed, 5 insertions(+), 49 deletions(-) delete mode 100644 dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/SchemaTypesTest.php diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php b/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php index e46fac2fed6ae..ebb9344e17d82 100644 --- a/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php +++ b/app/code/Magento/AsynchronousOperations/Model/BulkStatus.php @@ -57,12 +57,12 @@ class BulkStatus implements BulkStatusInterface private $entityManager; /** - * @var \Magento\AsynchronousOperations\Api\Data\DetailedBulkStatusInterfaceFactory + * @var BulkStatusDetailedFactory */ private $bulkDetailedFactory; /** - * @var \Magento\AsynchronousOperations\Api\Data\BulkStatus\ShortInterfaceFactory + * @var BulkStatusShortFactory */ private $bulkShortFactory; @@ -74,8 +74,8 @@ class BulkStatus implements BulkStatusInterface * @param \Magento\Framework\App\ResourceConnection $resourceConnection * @param \Magento\AsynchronousOperations\Model\BulkStatus\CalculatedStatusSql $calculatedStatusSql * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool - * @param \Magento\AsynchronousOperations\Api\Data\DetailedBulkStatusInterfaceFactory $bulkDetailedFactory - * @param \Magento\AsynchronousOperations\Api\Data\BulkStatusInterfaceFactory $bulkShortFactory + * @param BulkStatusDetailedFactory $bulkDetailedFactory + * @param BulkStatusShortFactory $bulkShortFactory * @param \Magento\Framework\EntityManager\EntityManager $entityManager */ public function __construct( diff --git a/app/code/Magento/AsynchronousOperations/etc/di.xml b/app/code/Magento/AsynchronousOperations/etc/di.xml index 39d295795f727..845c19fe93c11 100644 --- a/app/code/Magento/AsynchronousOperations/etc/di.xml +++ b/app/code/Magento/AsynchronousOperations/etc/di.xml @@ -11,6 +11,7 @@ + diff --git a/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/SchemaTypesTest.php b/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/SchemaTypesTest.php deleted file mode 100644 index f1e5ddfa86882..0000000000000 --- a/dev/tests/integration/testsuite/Magento/SwaggerWebapiAsync/Block/Swagger/SchemaTypesTest.php +++ /dev/null @@ -1,45 +0,0 @@ -get(\Magento\Framework\App\State::class) - ->setAreaCode('frontend'); - - $this->schemaTypes = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Swagger\Api\Block\SchemaTypesInterface::class - ); - } - - /** - * Test that the Swagger SchemaTypes contains the type added by SwaggerWebapiAsync. - */ - public function testContainsSchemaType() - { - $schemaExists = function() { - foreach ($this->schemaTypes->getTypes() as $schemaType) { - // @todo: implement constant once merged with other bulk-api changes - if ($schemaType->getCode() === 'async') { - return true; - } - } - return false; - }; - - $this->assertTrue($schemaExists()); - } -} From 866abaa4dc44da3fbe95ad294305a8e23743b4be Mon Sep 17 00:00:00 2001 From: Eugene Tulika Date: Tue, 27 Mar 2018 19:55:41 -0500 Subject: [PATCH 274/668] magento-engcom/bulk-api#4 Support for Async operations in WebAPI - Moved ConfigInterface to Asynchronous operations - updated tests --- .../Model/ConfigInterface.php | 3 +- .../Model/MassConsumer.php | 2 +- .../Model/MassPublisher.php | 2 +- .../Model/MassSchedule.php | 2 +- .../Magento/SwaggerWebapiAsync/LICENSE.txt | 48 ++++++++++ .../SwaggerWebapiAsync/LICENSE_AFL.txt | 48 ++++++++++ .../Test/Unit/Model/SchemaType/AsyncTest.php | 4 +- .../RemoteServiceReader/Communication.php | 8 +- .../Config/RemoteServiceReader/Consumer.php | 6 +- .../Config/RemoteServiceReader/Publisher.php | 6 +- .../Config/RemoteServiceReader/Topology.php | 9 +- .../Rest/AsynchronousRequestProcessor.php | 4 +- .../Model/ServiceConfig/Converter.php | 4 +- .../Test/Unit/Controller/RestTest.php | 4 +- .../Model/ServiceConfig/SchemaLocatorTest.php | 2 +- app/etc/di.xml | 2 +- .../WebapiAsync/WebapiAsyncBaseTestCase.php | 90 ------------------- 17 files changed, 124 insertions(+), 120 deletions(-) rename app/code/Magento/{WebapiAsync => AsynchronousOperations}/Model/ConfigInterface.php (95%) create mode 100644 app/code/Magento/SwaggerWebapiAsync/LICENSE.txt create mode 100644 app/code/Magento/SwaggerWebapiAsync/LICENSE_AFL.txt delete mode 100644 dev/tests/api-functional/testsuite/Magento/WebapiAsync/WebapiAsyncBaseTestCase.php diff --git a/app/code/Magento/WebapiAsync/Model/ConfigInterface.php b/app/code/Magento/AsynchronousOperations/Model/ConfigInterface.php similarity index 95% rename from app/code/Magento/WebapiAsync/Model/ConfigInterface.php rename to app/code/Magento/AsynchronousOperations/Model/ConfigInterface.php index 39a7991fda680..c57e359caf66d 100644 --- a/app/code/Magento/WebapiAsync/Model/ConfigInterface.php +++ b/app/code/Magento/AsynchronousOperations/Model/ConfigInterface.php @@ -4,11 +4,10 @@ * See COPYING.txt for license details. */ -namespace Magento\WebapiAsync\Model; +namespace Magento\AsynchronousOperations\Model; use Magento\Framework\Communication\ConfigInterface as CommunicationConfig; use Magento\AsynchronousOperations\Api\Data\OperationInterface; -use Magento\AsynchronousOperations\Model\MassConsumer; /** * Class for accessing to Webapi_Async configuration. diff --git a/app/code/Magento/AsynchronousOperations/Model/MassConsumer.php b/app/code/Magento/AsynchronousOperations/Model/MassConsumer.php index 65d978f048464..88ae2813bef44 100644 --- a/app/code/Magento/AsynchronousOperations/Model/MassConsumer.php +++ b/app/code/Magento/AsynchronousOperations/Model/MassConsumer.php @@ -29,7 +29,7 @@ use Magento\Framework\Serialize\Serializer\Json; use Magento\AsynchronousOperations\Api\Data\OperationInterface; use Magento\Framework\Bulk\OperationManagementInterface; -use Magento\WebapiAsync\Model\ConfigInterface as AsyncConfig; +use Magento\AsynchronousOperations\Model\ConfigInterface as AsyncConfig; /** * Class Consumer used to process OperationInterface messages. diff --git a/app/code/Magento/AsynchronousOperations/Model/MassPublisher.php b/app/code/Magento/AsynchronousOperations/Model/MassPublisher.php index 608fd2acc7056..b18c375fda4ad 100644 --- a/app/code/Magento/AsynchronousOperations/Model/MassPublisher.php +++ b/app/code/Magento/AsynchronousOperations/Model/MassPublisher.php @@ -11,7 +11,7 @@ use Magento\Framework\MessageQueue\Publisher\ConfigInterface as PublisherConfig; use Magento\Framework\MessageQueue\Bulk\ExchangeRepository; use Magento\Framework\MessageQueue\EnvelopeFactory; -use Magento\WebapiAsync\Model\ConfigInterface as AsyncConfig; +use Magento\AsynchronousOperations\Model\ConfigInterface as AsyncConfig; use Magento\Framework\MessageQueue\PublisherInterface; use Magento\Framework\MessageQueue\MessageIdGeneratorInterface; diff --git a/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php b/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php index cdb34fb6151ab..021202ffb69f1 100644 --- a/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php +++ b/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php @@ -128,7 +128,7 @@ public function __construct( */ public function publishMass($topicName, array $entitiesArray, $groupId = null, $userId = null) { - $bulkDescription = __('Topic %s', $topicName); + $bulkDescription = __('Topic %1', $topicName); if ($groupId == null) { $groupId = $this->identityService->generateId(); diff --git a/app/code/Magento/SwaggerWebapiAsync/LICENSE.txt b/app/code/Magento/SwaggerWebapiAsync/LICENSE.txt new file mode 100644 index 0000000000000..49525fd99da9c --- /dev/null +++ b/app/code/Magento/SwaggerWebapiAsync/LICENSE.txt @@ -0,0 +1,48 @@ + +Open Software License ("OSL") v. 3.0 + +This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: + +Licensed under the Open Software License version 3.0 + + 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: + + 1. to reproduce the Original Work in copies, either alone or as part of a collective work; + + 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; + + 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License; + + 4. to perform the Original Work publicly; and + + 5. to display the Original Work publicly. + + 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. + + 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. + + 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. + + 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). + + 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. + + 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. + + 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. + + 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including 'fair use' or 'fair dealing'). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). + + 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. + + 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. + + 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. + + 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. + + 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. + + 16. Modification of This License. This License is Copyright (C) 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under " or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. \ No newline at end of file diff --git a/app/code/Magento/SwaggerWebapiAsync/LICENSE_AFL.txt b/app/code/Magento/SwaggerWebapiAsync/LICENSE_AFL.txt new file mode 100644 index 0000000000000..f39d641b18a19 --- /dev/null +++ b/app/code/Magento/SwaggerWebapiAsync/LICENSE_AFL.txt @@ -0,0 +1,48 @@ + +Academic Free License ("AFL") v. 3.0 + +This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: + +Licensed under the Academic Free License version 3.0 + + 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: + + 1. to reproduce the Original Work in copies, either alone or as part of a collective work; + + 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; + + 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor's reserved rights and remedies, in this Academic Free License; + + 4. to perform the Original Work publicly; and + + 5. to display the Original Work publicly. + + 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. + + 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. + + 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. + + 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). + + 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. + + 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. + + 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. + + 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). + + 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. + + 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. + + 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. + + 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. + + 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. + + 16. Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under " or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. diff --git a/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php b/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php index 1e1ab3c50fe5e..c7a62dcdca3fd 100644 --- a/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php +++ b/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php @@ -25,7 +25,7 @@ protected function setUp() } /** - * @covers \Magento\SwaggerWebapi\Model\SchemaType\Async::getCode() + * @covers \Magento\SwaggerWebapiAsync\Model\SchemaType\Async::getCode() */ public function testGetCode() { @@ -33,7 +33,7 @@ public function testGetCode() } /** - * @covers \Magento\SwaggerWebapi\Model\SchemaType\Async::getSchemaUrlPathProvider + * @covers \Magento\SwaggerWebapiAsync\Model\SchemaType\Async::getSchemaUrlPathProvider * * @param null|string $store * @param $expected diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php index 2e07e26fda8fb..f6d3b158b8958 100644 --- a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Communication.php @@ -7,7 +7,7 @@ namespace Magento\WebapiAsync\Code\Generator\Config\RemoteServiceReader; use Magento\Framework\Communication\ConfigInterface as CommunicationConfig; -use Magento\WebapiAsync\Model\ConfigInterface as WebApiAsyncConfig; +use Magento\AsynchronousOperations\Model\ConfigInterface as WebApiAsyncConfig; use Magento\Framework\Communication\Config\ReflectionGenerator; /** @@ -17,7 +17,7 @@ class Communication implements \Magento\Framework\Config\ReaderInterface { /** - * @var \Magento\WebapiAsync\Model\ConfigInterface + * @var WebApiAsyncConfig */ private $webapiAsyncConfig; @@ -29,8 +29,8 @@ class Communication implements \Magento\Framework\Config\ReaderInterface /** * Initialize dependencies. * - * @param \Magento\WebapiAsync\Model\ConfigInterface $webapiAsyncConfig - * @param \Magento\Framework\Communication\Config\ReflectionGenerator $reflectionGenerator + * @param WebApiAsyncConfig $webapiAsyncConfig + * @param ReflectionGenerator $reflectionGenerator */ public function __construct( WebApiAsyncConfig $webapiAsyncConfig, diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php index 373ccc1041e43..f94971a1a22ec 100644 --- a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Consumer.php @@ -6,7 +6,7 @@ namespace Magento\WebapiAsync\Code\Generator\Config\RemoteServiceReader; -use Magento\WebapiAsync\Model\ConfigInterface as WebApiAsyncConfig; +use Magento\AsynchronousOperations\Model\ConfigInterface as WebApiAsyncConfig; /** * Remote service reader with auto generated configuration for queue_consumer.xml @@ -14,14 +14,14 @@ class Consumer implements \Magento\Framework\Config\ReaderInterface { /** - * @var \Magento\WebapiAsync\Model\ConfigInterface + * @var WebApiAsyncConfig */ private $webapiAsyncConfig; /** * Initialize dependencies. * - * @param \Magento\WebapiAsync\Model\ConfigInterface $webapiAsyncConfig + * @param WebApiAsyncConfig $webapiAsyncConfig */ public function __construct( WebApiAsyncConfig $webapiAsyncConfig diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php index c221908efde19..0be6c64890737 100644 --- a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Publisher.php @@ -6,7 +6,7 @@ namespace Magento\WebapiAsync\Code\Generator\Config\RemoteServiceReader; -use Magento\WebapiAsync\Model\ConfigInterface as WebApiAsyncConfig; +use Magento\AsynchronousOperations\Model\ConfigInterface as WebApiAsyncConfig; /** * Remote service reader with auto generated configuration for queue_publisher.xml @@ -15,14 +15,14 @@ class Publisher implements \Magento\Framework\Config\ReaderInterface { /** - * @var \Magento\WebapiAsync\Model\ConfigInterface + * @var WebApiAsyncConfig */ private $webapiAsyncConfig; /** * Initialize dependencies. * - * @param \Magento\WebapiAsync\Model\ConfigInterface $webapiAsyncConfig + * @param WebApiAsyncConfig $webapiAsyncConfig */ public function __construct( WebApiAsyncConfig $webapiAsyncConfig diff --git a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php index c6f2e36760a95..fc0504c421f88 100644 --- a/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php +++ b/app/code/Magento/WebapiAsync/Code/Generator/Config/RemoteServiceReader/Topology.php @@ -6,7 +6,7 @@ namespace Magento\WebapiAsync\Code\Generator\Config\RemoteServiceReader; -use Magento\WebapiAsync\Model\ConfigInterface as WebApiAsyncConfig; +use Magento\AsynchronousOperations\Model\ConfigInterface as WebApiAsyncConfig; use Magento\Framework\Communication\Config\ReflectionGenerator; /** @@ -16,7 +16,7 @@ class Topology implements \Magento\Framework\Config\ReaderInterface { /** - * @var \Magento\WebapiAsync\Model\ConfigInterface + * @var WebApiAsyncConfig */ private $webapiAsyncConfig; @@ -26,9 +26,10 @@ class Topology implements \Magento\Framework\Config\ReaderInterface private $reflectionGenerator; /** - * Initialize dependencies. + * Topology constructor. * - * @param \Magento\WebapiAsync\Model\ConfigInterface $webapiAsyncConfig + * @param WebApiAsyncConfig $webapiAsyncConfig + * @param ReflectionGenerator $reflectionGenerator */ public function __construct( WebApiAsyncConfig $webapiAsyncConfig, diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php index f1ac64f5bc720..934f9375c017f 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php @@ -11,7 +11,7 @@ use Magento\Framework\Webapi\Rest\Response as RestResponse; use Magento\WebapiAsync\Controller\Rest\Async\InputParamsResolver; use Magento\AsynchronousOperations\Model\MassSchedule; -use Magento\WebapiAsync\Model\ConfigInterface as WebApiAsyncConfig; +use Magento\AsynchronousOperations\Model\ConfigInterface as WebApiAsyncConfig; use Magento\Framework\Reflection\DataObjectProcessor; use Magento\AsynchronousOperations\Api\Data\AsyncResponseInterfaceFactory; use Magento\AsynchronousOperations\Api\Data\AsyncResponseInterface; @@ -36,7 +36,7 @@ class AsynchronousRequestProcessor implements RequestProcessorInterface private $asyncBulkPublisher; /** - * @var \Magento\WebapiAsync\Model\ConfigInterface + * @var WebApiAsyncConfig */ private $webapiAsyncConfig; diff --git a/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php b/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php index 1b2ccfdcbc75a..9151954a7cbd0 100644 --- a/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php +++ b/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php @@ -34,13 +34,11 @@ public function convert($source) if (!$this->canConvertXmlNode($service)) { continue; } - $serviceClass = $this->getServiceClass($service); $serviceMethod = $this->getServiceMethod($service); // Define the service method's key if this hasn't yet been defined $this->initServiceMethodsKey($result, $serviceClass, $serviceMethod); - $this->mergeSynchronousInvocationMethodsData($service, $result, $serviceClass, $serviceMethod); } @@ -145,7 +143,7 @@ private function getSynchronousMethodInvocationOnly(\DOMElement $serviceNode) * @param \DOMElement $synchronousInvocationOnlyNode * @return bool|mixed */ - private function isSynchronousInvocationOnlyTrue(\DOMElement $synchronousInvocationOnlyNode) + private function isSynchronousInvocationOnlyTrue(\DOMElement $synchronousInvocationOnlyNode = null) { if ($synchronousInvocationOnlyNode === null) { return false; diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php index f964b1cba3069..62a63f54fff74 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php +++ b/app/code/Magento/WebapiAsync/Test/Unit/Controller/RestTest.php @@ -196,7 +196,7 @@ public function testDispatchSchemaRequest() $schema = 'Some REST schema content'; $this->swaggerGeneratorMock->expects($this->any())->method('generate')->willReturn($schema); - $this->requestProcessorPool->process($this->requestMock); + $this->requestProcessorPool->getProcessor($this->requestMock)->process($this->requestMock); $this->assertEquals($schema, $this->responseMock->getBody()); } @@ -229,7 +229,7 @@ public function testDispatchAllSchemaRequest() $schema = 'Some REST schema content'; $this->swaggerGeneratorMock->expects($this->any())->method('generate')->willReturn($schema); - $this->requestProcessorPool->process($this->requestMock); + $this->requestProcessorPool->getProcessor($this->requestMock)->process($this->requestMock); $this->assertEquals($schema, $this->responseMock->getBody()); } diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/SchemaLocatorTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/SchemaLocatorTest.php index ccec768a36cdf..886b537e25331 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/SchemaLocatorTest.php +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/SchemaLocatorTest.php @@ -19,7 +19,7 @@ class SchemaLocatorTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->moduleReaderMock = $this->createPartialMock( + $this->moduleReaderMock = $this->createPartialMock( \Magento\Framework\Module\Dir\Reader::class, ['getModuleDir'] ); diff --git a/app/etc/di.xml b/app/etc/di.xml index 0d9392063397d..ebaf95a612ba9 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -218,7 +218,7 @@ Magento\Framework\Filesystem\Driver\File - + diff --git a/dev/tests/api-functional/testsuite/Magento/WebapiAsync/WebapiAsyncBaseTestCase.php b/dev/tests/api-functional/testsuite/Magento/WebapiAsync/WebapiAsyncBaseTestCase.php deleted file mode 100644 index 8b187c5e54f87..0000000000000 --- a/dev/tests/api-functional/testsuite/Magento/WebapiAsync/WebapiAsyncBaseTestCase.php +++ /dev/null @@ -1,90 +0,0 @@ -objectManager = Bootstrap::getObjectManager(); - $this->publisherConsumerController = $this->objectManager->create(PublisherConsumerController::class, [ - 'consumers' => $this->consumers, - 'logFilePath' => TESTS_TEMP_DIR . "/MessageQueueTestLog.txt", - 'maxMessages' => $this->maxMessages, - 'appInitParams' => \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams() - ]); - - try { - $this->publisherConsumerController->initialize(); - } catch (EnvironmentPreconditionException $e) { - $this->markTestSkipped($e->getMessage()); - } catch (PreconditionFailedException $e) { - $this->fail( - $e->getMessage() - ); - } - } - - protected function tearDown() - { - $this->publisherConsumerController->stopConsumers(); - parent::tearDown(); - } - - /** - * Workaround for https://bugs.php.net/bug.php?id=72286 - */ - public static function tearDownAfterClass() - { - if (version_compare(phpversion(), '7') == -1) { - $closeConnection = new \ReflectionMethod(\Magento\Amqp\Model\Config::class, 'closeConnection'); - $closeConnection->setAccessible(true); - - $config = Bootstrap::getObjectManager()->get(\Magento\Amqp\Model\Config::class); - $closeConnection->invoke($config); - } - parent::tearDownAfterClass(); - } -} \ No newline at end of file From 8eaa9d40a9a324445ea363a529a7fddd56f2a34a Mon Sep 17 00:00:00 2001 From: Eugene Tulika Date: Tue, 27 Mar 2018 20:14:06 -0500 Subject: [PATCH 275/668] magento-engcom/bulk-api#4 Support for Async operations in WebAPI - Updated the interface of the Config --- app/code/Magento/WebapiAsync/Model/Config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/WebapiAsync/Model/Config.php b/app/code/Magento/WebapiAsync/Model/Config.php index 335d300393572..1b2402ce77373 100644 --- a/app/code/Magento/WebapiAsync/Model/Config.php +++ b/app/code/Magento/WebapiAsync/Model/Config.php @@ -13,7 +13,7 @@ use Magento\Framework\Exception\LocalizedException; use Magento\Webapi\Model\Config\Converter; -class Config implements ConfigInterface +class Config implements \Magento\AsynchronousOperations\Model\ConfigInterface { /** * @var \Magento\Webapi\Model\Cache\Type\Webapi From a9133c2c580f2b15b033407465043a22fe60e606 Mon Sep 17 00:00:00 2001 From: Eugene Tulika Date: Tue, 27 Mar 2018 20:32:10 -0500 Subject: [PATCH 276/668] magento-engcom/bulk-api#4 Support for Async operations in WebAPI - Fixed static tests --- app/code/Magento/Swagger/composer.json | 1 - .../SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php | 2 +- app/code/Magento/SwaggerWebapiAsync/composer.json | 1 - .../testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Swagger/composer.json b/app/code/Magento/Swagger/composer.json index 9bacd69f161f5..6497f401d659c 100644 --- a/app/code/Magento/Swagger/composer.json +++ b/app/code/Magento/Swagger/composer.json @@ -7,7 +7,6 @@ "require": { "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", "magento/framework": "100.3.*", - "magento/module-webapi": "100.3.*" }, "type": "magento2-module", "version": "100.3.0-dev", diff --git a/app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php b/app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php index 44b348cb57087..7df71cbb440b1 100644 --- a/app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php +++ b/app/code/Magento/SwaggerWebapi/Test/Unit/Model/SchemaType/RestTest.php @@ -25,7 +25,7 @@ protected function setUp() } /** - * @covers \Magento\SwaggerWebapi\Model\SchemaType\Rest::getSchemaUrlPathProvider + * @covers \Magento\SwaggerWebapi\Model\SchemaType\Rest::getSchemaUrlPath * * @param $expected * @param null|string $store diff --git a/app/code/Magento/SwaggerWebapiAsync/composer.json b/app/code/Magento/SwaggerWebapiAsync/composer.json index 435585e731f05..6ca412c3f717c 100644 --- a/app/code/Magento/SwaggerWebapiAsync/composer.json +++ b/app/code/Magento/SwaggerWebapiAsync/composer.json @@ -7,7 +7,6 @@ "require": { "magento/framework": "100.3.*", "magento/module-swagger": "100.3.*", - "magento/module-webapi-async": "100.3.*", "php": "7.0.2|7.0.4|~7.0.6|~7.1.0" }, "suggest": { diff --git a/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php b/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php index 6f27c2bfd787c..712fc417bda9d 100644 --- a/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php +++ b/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\WebapiAsync\Model\MessageQueue; +namespace Magento\WebapiAsync\Model; use Magento\Catalog\Api\Data\ProductInterface; use Magento\TestFramework\MessageQueue\PreconditionFailedException; From b4375fe95757d5de15b2550c047be970b1bf86b4 Mon Sep 17 00:00:00 2001 From: Eugene Tulika Date: Tue, 27 Mar 2018 20:48:51 -0500 Subject: [PATCH 277/668] magento-engcom/bulk-api#4 Support for Async operations in WebAPI - Fixed static tests --- app/code/Magento/Swagger/composer.json | 2 +- .../SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Swagger/composer.json b/app/code/Magento/Swagger/composer.json index 6497f401d659c..5ea14336944d9 100644 --- a/app/code/Magento/Swagger/composer.json +++ b/app/code/Magento/Swagger/composer.json @@ -6,7 +6,7 @@ }, "require": { "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", - "magento/framework": "100.3.*", + "magento/framework": "100.3.*" }, "type": "magento2-module", "version": "100.3.0-dev", diff --git a/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php b/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php index c7a62dcdca3fd..45d29745b80df 100644 --- a/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php +++ b/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\SwaggerWebapi\Test\Unit\Model\SchemaType; +namespace Magento\SwaggerWebapiAsync\Test\Unit\Model\SchemaType; use Magento\Swagger\Api\Data\SchemaTypeInterface; use Magento\SwaggerWebapiAsync\Model\SchemaType\Async; From 088582896312a0c6af96e56816eaef48c10c5edc Mon Sep 17 00:00:00 2001 From: Eugene Tulika Date: Tue, 27 Mar 2018 21:14:31 -0500 Subject: [PATCH 278/668] magento-engcom/bulk-api#4 Support for Async operations in WebAPI - Fixed static tests --- .../Test/Unit/Model/ServiceConfigTest.php | 2 +- .../Framework/MessageQueue/MergerFactory.php | 50 ++----------------- 2 files changed, 4 insertions(+), 48 deletions(-) diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfigTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfigTest.php index c21c5181ae208..283bfe9b7742f 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfigTest.php +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfigTest.php @@ -3,7 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Webapi\Test\Unit\Model; +namespace Magento\WebapiAsync\Test\Unit\Model; use Magento\Framework\Serialize\SerializerInterface; use Magento\Webapi\Model\Cache\Type\Webapi; diff --git a/lib/internal/Magento/Framework/MessageQueue/MergerFactory.php b/lib/internal/Magento/Framework/MessageQueue/MergerFactory.php index c877c80e0c579..0647279258ae2 100644 --- a/lib/internal/Magento/Framework/MessageQueue/MergerFactory.php +++ b/lib/internal/Magento/Framework/MessageQueue/MergerFactory.php @@ -3,7 +3,6 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Framework\MessageQueue; use Magento\Framework\ObjectManagerInterface; @@ -25,7 +24,7 @@ class MergerFactory * @param ObjectManagerInterface $objectManager * @param string[] $mergers */ - public function __construct(ObjectManagerInterface $objectManager, $mergers) + public function __construct(ObjectManagerInterface $objectManager, $mergers = []) { $this->objectManager = $objectManager; $this->mergers = $mergers; @@ -38,18 +37,11 @@ public function __construct(ObjectManagerInterface $objectManager, $mergers) */ public function create($consumerName) { - $matchMergerWildcard = $this->matchConsumer($consumerName); - - if (!isset($this->mergers[$consumerName]) && !isset($matchMergerWildcard)) { + if (!isset($this->mergers[$consumerName])) { throw new \LogicException("Not found merger for consumer name '{$consumerName}'"); } - if (isset($this->mergers[$consumerName])) { - $mergerClassName = $this->mergers[$consumerName]; - } else { - $mergerClassName = $this->mergers[$matchMergerWildcard]; - } - + $mergerClassName = $this->mergers[$consumerName]; $merger = $this->objectManager->get($mergerClassName); if (!$merger instanceof MergerInterface) { @@ -62,40 +54,4 @@ public function create($consumerName) return $merger; } - - /** - * @param $consumerName - * @return string|null - */ - private function matchConsumer($consumerName) - { - $patterns = []; - foreach (array_keys($this->mergers) as $mergerFor) { - if (strpos($mergerFor, '*') !== false || strpos($mergerFor, '#') !== false) { - $patterns[$mergerFor] = $this->buildWildcardPattern($mergerFor); - } - } - - foreach ($patterns as $mergerKey => $pattern) { - if (preg_match($pattern, $consumerName)) { - return $mergerKey; - } - } - } - - /** - * Construct perl regexp pattern for matching topic names from wildcard key. - * - * @param string $wildcardKey - * @return string - */ - private function buildWildcardPattern($wildcardKey) - { - $pattern = '/^' . str_replace('.', '\.', $wildcardKey); - $pattern = str_replace('#', '.+', $pattern); - $pattern = str_replace('*', '[^\.]+', $pattern); - $pattern .= strpos($wildcardKey, '#') === strlen($wildcardKey) ? '/' : '$/'; - - return $pattern; - } } From d73da4aa6ad9bd8ef07d9083d4c0d5071e983615 Mon Sep 17 00:00:00 2001 From: Eugene Tulika Date: Tue, 27 Mar 2018 21:41:28 -0500 Subject: [PATCH 279/668] magento-engcom/bulk-api#4 Support for Async operations in WebAPI - Fixed static tests --- .../Api/Data/AsyncResponseInterface.php | 6 +-- .../Model/AsyncResponse.php | 8 ++-- .../Model/MassSchedule.php | 3 ++ .../Test/Unit/Model/SchemaType/AsyncTest.php | 10 ++--- .../Rest/AsynchronousRequestProcessor.php | 1 - .../WebapiAsync/Plugin/ServiceMetadata.php | 2 + .../Unit/Model/ServiceConfig/ReaderTest.php | 6 +-- .../WebapiAsync/Model/BulkScheduleTest.php | 37 ++++++++++++++----- .../Model/MassScheduleTest.php | 25 +++++++------ .../UseCase/QueueTestCaseAbstract.php | 3 +- .../WebapiAsync/Model/AuthorizationMock.php | 1 + 11 files changed, 63 insertions(+), 39 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/AsyncResponseInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/AsyncResponseInterface.php index 19f87c55ed60e..b56e1327aee3e 100644 --- a/app/code/Magento/AsynchronousOperations/Api/Data/AsyncResponseInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/Data/AsyncResponseInterface.php @@ -16,7 +16,7 @@ interface AsyncResponseInterface { const BULK_UUID = 'bulk_uuid'; const REQUEST_ITEMS = 'request_items'; - const IS_ERRORS = 'is_errors'; + const ERRORS = 'errors'; /** * Gets the bulk uuid. @@ -52,14 +52,14 @@ public function setRequestItems($requestItems); * @param bool $isErrors * @return $this */ - public function setIsErrors($isErrors = false); + public function setErrors($isErrors = false); /** * Is there errors during processing bulk * * @return boolean */ - public function getIsErrors(); + public function isErrors(); /** * Retrieve existing extension attributes object. diff --git a/app/code/Magento/AsynchronousOperations/Model/AsyncResponse.php b/app/code/Magento/AsynchronousOperations/Model/AsyncResponse.php index 23447ddea82ba..405c84770cb6c 100644 --- a/app/code/Magento/AsynchronousOperations/Model/AsyncResponse.php +++ b/app/code/Magento/AsynchronousOperations/Model/AsyncResponse.php @@ -47,17 +47,17 @@ public function setRequestItems($requestItems) /** * @inheritdoc */ - public function setIsErrors($isErrors = false) + public function setErrors($isErrors = false) { - return $this->setData(self::IS_ERRORS, $isErrors); + return $this->setData(self::ERRORS, $isErrors); } /** * @inheritdoc */ - public function getIsErrors() + public function isErrors() { - return $this->getData(self::IS_ERRORS); + return $this->getData(self::ERRORS); } /** diff --git a/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php b/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php index 021202ffb69f1..eaa9f8d968eb5 100644 --- a/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php +++ b/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php @@ -24,6 +24,8 @@ /** * Class MassSchedule used for adding multiple entities as Operations to Bulk Management with the status tracking + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class MassSchedule { @@ -90,6 +92,7 @@ class MassSchedule * @param MessageValidator $messageValidator * @param BulkManagementInterface $bulkManagement * @param LoggerInterface $logger + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( OperationInterfaceFactory $operationFactory, diff --git a/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php b/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php index 45d29745b80df..c78f2c786b7c5 100644 --- a/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php +++ b/app/code/Magento/SwaggerWebapiAsync/Test/Unit/Model/SchemaType/AsyncTest.php @@ -40,7 +40,7 @@ public function testGetCode() * * @dataProvider getSchemaUrlPathProvider */ - public function testGetSchemaUrlPath($store = null, $expected) + public function testGetSchemaUrlPath($expected, $store = null) { $this->assertEquals($expected, $this->async->getSchemaUrlPath($store)); } @@ -52,12 +52,12 @@ public function getSchemaUrlPathProvider() { return [ [ - null, - '/rest/all/async/schema?services=all' + '/rest/all/async/schema?services=all', + null ], [ - 'test', - '/rest/test/async/schema?services=all' + '/rest/test/async/schema?services=all', + 'test' ] ]; } diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php index 934f9375c017f..2fdbd25f0d2cb 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php @@ -89,7 +89,6 @@ public function process(\Magento\Framework\Webapi\Rest\Request $request) $entitiesParamsArray = $this->inputParamsResolver->resolve(); $topicName = $this->getTopicName($request); - $requestItemsList = null; try { $asyncResponse = $this->asyncBulkPublisher->publishMass( diff --git a/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php b/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php index c52ac0930177c..ce9ab2a2dd9b8 100644 --- a/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php +++ b/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php @@ -69,6 +69,7 @@ public function __construct( * @param \Magento\Webapi\Model\ServiceMetadata $subject * @param array $result * @return array + * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function afterGetServicesConfig(\Magento\Webapi\Model\ServiceMetadata $subject, array $result) { @@ -154,6 +155,7 @@ private function getSynchronousOnlyServiceMethods(\Magento\Webapi\Model\ServiceM * * @param \Magento\Webapi\Model\ServiceMetadata $serviceMetadata * @return array + * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ private function getSynchronousOnlyRoutesAsServiceMethods( \Magento\Webapi\Model\ServiceMetadata $serviceMetadata diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ReaderTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ReaderTest.php index a7251d169d506..481ec80e54d51 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ReaderTest.php +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/ReaderTest.php @@ -43,12 +43,10 @@ public function testReader() { $this->fileResolver->expects($this->once()) ->method('get') - ->with('webapi_async.xml', 'global')->willReturn( - [ + ->with('webapi_async.xml', 'global')->willReturn([ file_get_contents(__DIR__ . '/_files/Reader/webapi_async_1.xml'), file_get_contents(__DIR__ . '/_files/Reader/webapi_async_2.xml'), - ] - ); + ]); $mergedConfiguration = include __DIR__ . '/_files/Reader/webapi_async.php'; $readConfiguration = $this->reader->read(); diff --git a/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php b/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php index 712fc417bda9d..26fc699859be5 100644 --- a/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php +++ b/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/BulkScheduleTest.php @@ -24,6 +24,7 @@ * check if product was created by async requests * * @magentoAppIsolation enabled + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class BulkScheduleTest extends WebapiAbstract { @@ -98,7 +99,6 @@ protected function setUp() } parent::setUp(); - } /** @@ -114,21 +114,22 @@ public function testAsyncScheduleBulk($product) $this->skus[] = $product['product'][ProductInterface::SKU]; $this->assertCount(1, $response['request_items']); $this->assertEquals('accepted', $response['request_items'][0]['status']); - $this->assertFalse($response['is_errors']); + $this->assertFalse($response['errors']); } else { $this->assertCount(count($product), $response['request_items']); - foreach($product as $productItem) { + foreach ($product as $productItem) { $this->skus[] = $productItem['product'][ProductInterface::SKU]; } foreach ($response['request_items'] as $status) { $this->assertEquals('accepted', $status['status']); } - $this->assertFalse($response['is_errors']); + $this->assertFalse($response['errors']); } //assert one products is created try { $this->publisherConsumerController->waitForAsynchronousResult( - [$this, 'assertProductCreation'], [$product] + [$this, 'assertProductCreation'], + [$product] ); } catch (PreconditionFailedException $e) { $this->fail("Not all products were created"); @@ -210,11 +211,27 @@ public function productCreationProvider() }; return [ - [['product' => $productBuilder([ProductInterface::TYPE_ID => 'simple', ProductInterface::SKU => 'psku-test-1'])]], - [['product' => $productBuilder([ProductInterface::TYPE_ID => 'virtual', ProductInterface::SKU => 'psku-test-2'])]], + [ + ['product' => + $productBuilder([ + ProductInterface::TYPE_ID => 'simple', + ProductInterface::SKU => 'psku-test-1' + ]) + ] + ], + [['product' => $productBuilder([ + ProductInterface::TYPE_ID => 'virtual', + ProductInterface::SKU => 'psku-test-2']) + ]], [[ - ['product' => $productBuilder([ProductInterface::TYPE_ID => 'simple', ProductInterface::SKU => 'psku-test-1'])], - ['product' => $productBuilder([ProductInterface::TYPE_ID => 'virtual', ProductInterface::SKU => 'psku-test-2'])] + ['product' => $productBuilder([ + ProductInterface::TYPE_ID => 'simple', + ProductInterface::SKU => 'psku-test-1' + ])], + ['product' => $productBuilder([ + ProductInterface::TYPE_ID => 'virtual', + ProductInterface::SKU => 'psku-test-2' + ])] ]] ]; } @@ -272,7 +289,7 @@ private function saveProductAsync($requestData, $storeCode = null) return $this->_webApiCall($serviceInfo, $requestData, null, $storeCode); } - public function assertProductCreation($product) + public function assertProductCreation() { $collection = $this->objectManager->create(Collection::class) ->addAttributeToFilter('sku', ['in' => $this->skus]) diff --git a/dev/tests/integration/testsuite/Magento/AsynchronousOperations/Model/MassScheduleTest.php b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/Model/MassScheduleTest.php index 0f3aa9c923a18..3cd6b3517f078 100644 --- a/dev/tests/integration/testsuite/Magento/AsynchronousOperations/Model/MassScheduleTest.php +++ b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/Model/MassScheduleTest.php @@ -24,6 +24,9 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\ObjectManagerInterface; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class MassScheduleTest extends \PHPUnit\Framework\TestCase { /** @@ -86,13 +89,10 @@ protected function setUp() } catch (EnvironmentPreconditionException $e) { $this->markTestSkipped($e->getMessage()); } catch (PreconditionFailedException $e) { - $this->fail( - $e->getMessage() - ); + $this->fail($e->getMessage()); } parent::setUp(); - } /** @@ -102,7 +102,8 @@ protected function setUp() * @dataProvider productDataProvider * @param ProductInterface[] $products */ - public function testScheduleMass($products) { + public function testScheduleMass($products) + { try { $this->sendBulk($products); } catch (BulkException $bulkException) { @@ -112,7 +113,8 @@ public function testScheduleMass($products) { //assert all products are created try { $this->publisherConsumerController->waitForAsynchronousResult( - [$this, 'assertProductExists'], [$this->skus, count($this->skus)] + [$this, 'assertProductExists'], + [$this->skus, count($this->skus)] ); } catch (PreconditionFailedException $e) { $this->fail("Not all products were created"); @@ -130,7 +132,7 @@ public function sendBulk($products) $result = $this->massSchedule->publishMass('async.V1.products.POST', $products); //assert bulk accepted with no errors - $this->assertFalse($result->getIsErrors()); + $this->assertFalse($result->isErrors()); //assert number of products sent to queue $this->assertCount(count($this->skus), $result->getRequestItems()); @@ -199,7 +201,6 @@ public function testScheduleMassOneEntityFailure($products) } catch (BulkException $e) { $this->assertCount(1, $e->getErrors()); - $errors = $e->getErrors(); $this->assertInstanceOf(\Magento\Framework\Exception\LocalizedException::class, $errors[0]); @@ -207,7 +208,8 @@ public function testScheduleMassOneEntityFailure($products) $reasonException = $errors[0]->getPrevious(); - $expectedErrorMessage = "Data item corresponding to \"product\" must be specified in the message with topic " . + $expectedErrorMessage = "Data item corresponding to \"product\" " . + "must be specified in the message with topic " . "\"async.V1.products.POST\"."; $this->assertEquals( $expectedErrorMessage, @@ -216,7 +218,7 @@ public function testScheduleMassOneEntityFailure($products) /** @var \Magento\WebapiAsync\Model\AsyncResponse $bulkStatus */ $bulkStatus = $e->getData(); - $this->assertTrue($bulkStatus->getIsErrors()); + $this->assertTrue($bulkStatus->isErrors()); /** @var ItemStatus[] $items */ $items = $bulkStatus->getRequestItems(); @@ -233,7 +235,8 @@ public function testScheduleMassOneEntityFailure($products) //assert one products is created try { $this->publisherConsumerController->waitForAsynchronousResult( - [$this, 'assertProductExists'], [$this->skus, count($this->skus)] + [$this, 'assertProductExists'], + [$this->skus, count($this->skus)] ); } catch (PreconditionFailedException $e) { $this->fail("Not all products were created"); diff --git a/dev/tests/integration/testsuite/Magento/Framework/MessageQueue/UseCase/QueueTestCaseAbstract.php b/dev/tests/integration/testsuite/Magento/Framework/MessageQueue/UseCase/QueueTestCaseAbstract.php index 910ceb105ac30..bda232c7fb9c4 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/MessageQueue/UseCase/QueueTestCaseAbstract.php +++ b/dev/tests/integration/testsuite/Magento/Framework/MessageQueue/UseCase/QueueTestCaseAbstract.php @@ -93,7 +93,8 @@ protected function waitForAsynchronousResult($expectedLinesCount, $logFilePath) } } - public function checkLogsExists($expectedLinesCount) { + public function checkLogsExists($expectedLinesCount) + { $actualCount = file_exists($this->logFilePath) ? count(file($this->logFilePath)) : 0; return $expectedLinesCount === $actualCount; } diff --git a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/AuthorizationMock.php b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/AuthorizationMock.php index bb0b7f2fbc964..a09db933c4185 100644 --- a/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/AuthorizationMock.php +++ b/dev/tests/integration/testsuite/Magento/WebapiAsync/Model/AuthorizationMock.php @@ -12,6 +12,7 @@ class AuthorizationMock extends Authorization /** * @param string[] $aclResources * @return bool + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function isAllowed($aclResources) { From d5719d3f321289059e277acb4101f40730c2576c Mon Sep 17 00:00:00 2001 From: Yogesh Suhagiya Date: Sat, 24 Mar 2018 16:45:14 +0530 Subject: [PATCH 280/668] Added translation for delete confirm popup box --- .../adminhtml/templates/integration/popup_container.phtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Integration/view/adminhtml/templates/integration/popup_container.phtml b/app/code/Magento/Integration/view/adminhtml/templates/integration/popup_container.phtml index 6faeee56ba692..79c0e9846656d 100644 --- a/app/code/Magento/Integration/view/adminhtml/templates/integration/popup_container.phtml +++ b/app/code/Magento/Integration/view/adminhtml/templates/integration/popup_container.phtml @@ -33,8 +33,8 @@ $('div#integrationGrid').on('click', 'button#delete', function (e) { new Confirm({ - title: 'Are you sure?', - content: "Are you sure you want to delete this integration? You can't undo this action.", + title: '', + content: "", actions: { confirm: function () { window.location.href = $(e.target).data('url'); From 3a211c76c08aefe008249c30e84a768ad330459e Mon Sep 17 00:00:00 2001 From: Yogesh Suhagiya Date: Sat, 24 Mar 2018 16:48:02 +0530 Subject: [PATCH 281/668] Make proper sentence for confirm box --- app/code/Magento/Integration/i18n/en_US.csv | 2 +- .../view/adminhtml/templates/integration/popup_container.phtml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Integration/i18n/en_US.csv b/app/code/Magento/Integration/i18n/en_US.csv index 6fb5d2e071205..b225ad2766fff 100644 --- a/app/code/Magento/Integration/i18n/en_US.csv +++ b/app/code/Magento/Integration/i18n/en_US.csv @@ -93,7 +93,7 @@ Reset,Reset "A token with consumer ID 0 does not exist","A token with consumer ID 0 does not exist" "The integration you selected asks you to approve access to the following:","The integration you selected asks you to approve access to the following:" "No permissions requested","No permissions requested" -"Are you sure ?","Are you sure ?" +"Are you sure?","Are you sure?" "Are you sure you want to delete this integration? You can't undo this action.","Are you sure you want to delete this integration? You can't undo this action." "Please setup or sign in into your 3rd party account to complete setup of this integration.","Please setup or sign in into your 3rd party account to complete setup of this integration." "Available APIs","Available APIs" diff --git a/app/code/Magento/Integration/view/adminhtml/templates/integration/popup_container.phtml b/app/code/Magento/Integration/view/adminhtml/templates/integration/popup_container.phtml index 79c0e9846656d..626ab300824d2 100644 --- a/app/code/Magento/Integration/view/adminhtml/templates/integration/popup_container.phtml +++ b/app/code/Magento/Integration/view/adminhtml/templates/integration/popup_container.phtml @@ -51,7 +51,7 @@